<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.0.0">
  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">
  <link rel="alternate" href="/atom.xml" title="dy2903的博客" type="application/atom+xml">

<link rel="stylesheet" href="/css/main.css">


<link rel="stylesheet" href="/lib/font-awesome/css/font-awesome.min.css">


<script id="hexo-configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/',
    scheme: 'Pisces',
    version: '7.5.0',
    exturl: false,
    sidebar: {"position":"left","display":"post","offset":12,"onmobile":false},
    copycode: {"enable":false,"show_result":false,"style":null},
    back2top: {"enable":true,"sidebar":false,"scrollpercent":false},
    bookmark: {"enable":false,"color":"#222","save":"auto"},
    fancybox: false,
    mediumzoom: false,
    lazyload: false,
    pangu: false,
    algolia: {
      appID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    },
    localsearch: {"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},
    path: '',
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    translation: {
      copy_button: 'Copy',
      copy_success: 'Copied',
      copy_failure: 'Copy failed'
    },
    sidebarPadding: 40
  };
</script>

  <meta property="og:type" content="website">
<meta property="og:title" content="dy2903的博客">
<meta property="og:url" content="https:&#x2F;&#x2F;duyang2903.gitee.io&#x2F;index.html">
<meta property="og:site_name" content="dy2903的博客">
<meta property="og:locale" content="en">
<meta name="twitter:card" content="summary">

<link rel="canonical" href="https://duyang2903.gitee.io/">


<script id="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome: true,
    isPost: false,
    isPage: false,
    isArchive: false
  };
</script>

  <title>dy2903的博客</title>
  






  <noscript>
  <style>
  .use-motion .brand,
  .use-motion .menu-item,
  .sidebar-inner,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-header { opacity: initial; }

  .use-motion .site-title,
  .use-motion .site-subtitle {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line-before i { left: initial; }
  .use-motion .logo-line-after i { right: initial; }
  </style>
</noscript>

</head>

<body itemscope itemtype="http://schema.org/WebPage">
  <div class="container use-motion">
    <div class="headband"></div>

    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-meta">

    <div>
      <a href="/" class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">dy2903的博客</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
        <p class="site-subtitle">与肝胆人共事，从无字句读书</p>
  </div>

  <div class="site-nav-toggle">
    <div class="toggle" aria-label="Toggle navigation bar">
      <span class="toggle-line toggle-line-first"></span>
      <span class="toggle-line toggle-line-middle"></span>
      <span class="toggle-line toggle-line-last"></span>
    </div>
  </div>
</div>


<nav class="site-nav">
  
  <ul id="menu" class="menu">
        <li class="menu-item menu-item-home">

    <a href="/" rel="section"><i class="fa fa-fw fa-home"></i>Home</a>

  </li>
        <li class="menu-item menu-item-archives">

    <a href="/archives/" rel="section"><i class="fa fa-fw fa-archive"></i>Archives</a>

  </li>
  </ul>

</nav>
</div>
    </header>

    
  <div class="back-to-top">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>


    <main class="main">
      <div class="main-inner">
        <div class="content-wrap">
          

          <div class="content">
            

  <div class="posts-expand">
        
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="en">
    <link itemprop="mainEntityOfPage" href="https://duyang2903.gitee.io/2019/11/15/%E5%A4%A7%E8%AF%9D%E5%AD%98%E5%82%A8%EF%BC%8C%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%887,8%E7%AB%A0%EF%BC%89%EF%BC%8CFC%E5%8D%8F%E8%AE%AE/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="dy2903">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="dy2903的博客">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          
            <a href="/2019/11/15/%E5%A4%A7%E8%AF%9D%E5%AD%98%E5%82%A8%EF%BC%8C%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%887,8%E7%AB%A0%EF%BC%89%EF%BC%8CFC%E5%8D%8F%E8%AE%AE/" class="post-title-link" itemprop="url">大话存储，学习笔记（7,8章），FC协议</a>
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">Posted on</span>

              <time title="Created: 2019-11-15 10:48:24" itemprop="dateCreated datePublished" datetime="2019-11-15T10:48:24+08:00">2019-11-15</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">Edited on</span>
                <time title="Modified: 2019-11-13 21:27:13" itemprop="dateModified" datetime="2019-11-13T21:27:13+08:00">2019-11-13</time>
              </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <h1 id="Fibre-Channnel"><a href="#Fibre-Channnel" class="headerlink" title="Fibre Channnel"></a>Fibre Channnel</h1><p>我们之前引入了SAN的概念，SAN首先是个网络，而不是存储设备。这个网络是专门来给<strong>主机</strong>连接存储设备用的。</p>
<p>我们知道按照SCSI总线16个节点的限制，不可能接入很多的磁盘，要扩大SAN的规模，只使用SCSI总线是不行的，所以必须找到一种可寻址容量大、稳定性强、速度块、传输距离远的网络结构。FC网络就应运而生。</p>
<h2 id="FC网络"><a href="#FC网络" class="headerlink" title="FC网络"></a>FC网络</h2><p>Fibre Channnel也就是网状通道，FC协议从1988年出现，最开始作为高速骨干网技术。</p>
<p>任何互联系统都逃不过OSI模型，所以我们可以用OSI来将FC协议进行断层分析。</p>
<h3 id="物理层"><a href="#物理层" class="headerlink" title="物理层"></a>物理层</h3><p>首先有较高的速度：1Gb/s,2Gb/s,4Gb/s，8Gb/s到16Gbps</p>
<p>为了实现远距离传输，传输介质起码是<strong>光纤</strong></p>
<h3 id="链路层"><a href="#链路层" class="headerlink" title="链路层"></a>链路层</h3><h4 id="字符编码及FC帧结构"><a href="#字符编码及FC帧结构" class="headerlink" title="字符编码及FC帧结构"></a>字符编码及FC帧结构</h4><p>FC协议的帧头有24字节，比以太网帧头（14字节）还要长。</p>
<p>比如下图为以太网的报文格式。</p>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-73576bc9819d70d4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<p>为什么FC协议需要这么长的帧头呢？因为24字节的帧头不但包含了寻址功能，还包含了<strong>传输功能保障。</strong>也就是说网络层和传输层的逻辑都用这24字节来传输。</p>
<p>这点就与TCP/IP+以太网不同，以太网基本上没有传输功能保证功能，主要需要靠TCP来进行端到端的传输保障。</p>
<p>我们可以对比一下TCP/IP和FC协议的开销：</p>
<p>基于以太网的TCP/IP网络，开销为：</p>
<blockquote>
<p>14字节(以太网帧头) + 20字节（IP头） + 20字节（TCP头） =54字节，或者把TCP帧头变为UDP（8字节）一共是42字节</p>
</blockquote>
<p>而FC协议就24字节，所以开销比TCP/IP的要小。</p>
<h3 id="网络层"><a href="#网络层" class="headerlink" title="网络层"></a>网络层</h3><p>FC网络中的节点要通信，无非也就是<strong>连、找、发</strong>三大要素。</p>
<ul>
<li><p>连：通过FC交换机打通通路，主要的拓扑结构有FC-AL和Fabric两种。</p>
</li>
<li><p>找：FC协议有一套于以太网不相同的编址方式，可以尽可能减少人为的干预。</p>
</li>
<li><p>发：指的是与目标进行通信</p>
</li>
</ul>
<p>从这个方面基本上就可以了解FC各节点交互的流程了。</p>
<h4 id="连：拓扑"><a href="#连：拓扑" class="headerlink" title="连：拓扑"></a>连：拓扑</h4><p>与以太网类似，FC也有两种拓扑：FC-AL和Fabric</p>
<ul>
<li>FC-AL：类似以太网<strong>共享总线拓扑</strong>，但是连接方式不是总线，而是仲裁环（Arbitral loop）。每个FC -AL 设备首尾接成了一个环路。最多能接入128个节点，实际上只用了8位的寻址容量。被广播地址、专用地址占用之后，只剩下127个实际可用的地址。</li>
</ul>
<p>仲裁环是应该 由所有设备串联而成的闭合环路，每个接口上都有一套旁路电路（Bypass Circuit）,一旦检测到本地设备故障，就会自动将这个接口短路。</p>
<p>一跳一跳的传输，而且任何时候只能按照一个方向向下游传输。</p>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-7938957a77455401.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<ul>
<li>Fabric：与以太网交换拓扑类似。Fabric的意思是“网状构造”，表明其实是一种<strong>网状的交换矩阵</strong></li>
</ul>
<p>相对于仲裁环路来说<strong>转发效率提升了很多</strong>，联入矩阵所有节点可以同时进行<strong>点对点</strong>通信，加上<strong>包交换</strong>所带来的并发和资源充分利用，<strong>可使得交换架构获得的总带宽为所有端口带宽之和。</strong></p>
<p>而AL架构下，不管接入的节点有多少，带宽为恒定，即共享环路带宽。</p>
<p>下图为交换矩阵的示意图。<br><img src="http://upload-images.jianshu.io/upload_images/1323506-8493680ac336abde.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<p>FC终端设备接入矩阵端点，一个设备发给另一个设备数据帧被交换矩阵收到后，矩阵会拨动交叉处的开关，连通电路，传输数据。所以可以把交换矩阵是一个大的电路开关矩阵，根据通信的源和目的决定波动哪些开关。</p>
<p>FC交换拓扑寻址容量是2的24次方个地址，比以太网理论值（2的48次方）少，但是对于专用的存储网足够。</p>
<h4 id="找：编址"><a href="#找：编址" class="headerlink" title="找：编址"></a>找：编址</h4><p>任何网络都需要寻址机制，所以需要对FC网络的每个设备定义一个唯一的标识。</p>
<ul>
<li>WWNN（World Wide Node Name）：每个设备自身有一个WWNN</li>
<li>WWPN(World Wide Port Name)：FC设备的每个端口都一个WWPN，是世界上唯一的。</li>
</ul>
<p><strong>以太网交换设备的端口不需要有MAC地址</strong>，而FC交换机却需要每个端口<strong>都有自己的WWPN。</strong>这是因为FC要做的工作比以太网交换机多，许多FC的逻辑都集成在了FC交换机。 需要处理到FC协议的最上层。而以太网相对简单，因为上层逻辑都被交给TCP/IP这样的上层协议来实现了。</p>
<p>WWPN：长度是64位，比MAC地址多16位。长度太长，速度低，所以在WWPN上映射一层寻址机制，分配一个Fabric ID，嵌入链路帧里面来做路由</p>
<p>这样WWPN被映射到了Fabric ID，一个24位的Fabric ID又被分为Domain ID、Area ID、Port ID三个亚寻址单元</p>
<ul>
<li><p>高8位定义为Domain区分符，用来区分网络中的FC交换机本身。Domain ID是自主交换机分配的。那<strong>主交换机</strong>怎么来的？它是根据WWNN号来进行选举，WWNN最小者获胜，成为主交换机，它就有资格向其他交换机分配Domain ID</p>
</li>
<li><p>中8位定义为Area区分符，区分同一台交换机的不同端口组。如果一块芯片可以管理1、2、3、4号FC端口，那么芯片可以属于一个Area</p>
</li>
<li><p>低8位定义为Port区分符，区分不同的Port</p>
</li>
</ul>
<h4 id="发：地址映射过程"><a href="#发：地址映射过程" class="headerlink" title="发：地址映射过程"></a>发：地址映射过程</h4><p>如下的讲解主要是针对Fabric 交换架构网络。</p>
<p>既然要把WWPN映射到Fabric ID上，就一定要有映射机制，那么每个端口如何获得Fabric ID的呢？过程比较类似于RARP协议。</p>
<p>当一个端口接到FC网络的时候，会向注册服务器发送一个注册申请，然后这个注册服务器会返回给它<strong>动态分配</strong>一个Fabric ID。当然此时注册服务器会记录这个映射关系。</p>
<p><strong>此后这个接口的帧不会携带WWPN，而是携带其被分配的ID作为源地址。</strong>这点就与以太网不同，我们知道 以太网既携带MAC又携带IP，所以在效率上打了折扣。</p>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-64feaa2083a02cda.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<h4 id="发：同步其他节点信息"><a href="#发：同步其他节点信息" class="headerlink" title="发：同步其他节点信息"></a>发：同步其他节点信息</h4><p>不过还有一个问题，一个端口要与另一个端口通信，那么怎么知道要通信目标的Fabric ID是多少呢？</p>
<p>每个节点获得自己的Fabric ID之后，还会进行<strong>名称注册</strong>。同样也是向名称服务器发送注册帧，主动告知自己的Fabric ID等信息。然后名称服务器其他节点的信息返回给它。这样就知道了其他节点地址呢。</p>
<p>如果FC网络比较大，则可能不只一台FC交换机。也就是说有若干FC交换机互联。与IP网络不同的是，FC网络不需要<strong>太多的人工介入</strong>，它们会自动协商自己的Domain ID（可以回过去看看Fabric ID的结构），选举出主交换机，由主交换机来为其他的交换机分配Domain ID。交换机之间会运行OSPF等路由协议，这样可以交互节点信息，寻址各个节点。</p>
<p>现在我们可以与IP网络对比一下，IP网络需要很强的人为介入性，需要人来配置节点的IP地址、路由信息等，而FC网络则可以自动分配和管理地址。最根本原因是因为FC协议一开始设计就是为了高速、高效的网络，而不是给Internet使用的。所以自动分配地址当然适合。</p>
<h4 id="发：与目标通信"><a href="#发：与目标通信" class="headerlink" title="发：与目标通信"></a>发：与目标通信</h4><p>此时每个节点已经获得了Fabric ID了，同时还从名称服务器得知网络上其他节点的ID，万事俱备，完全可以与其他节点进行通信了。</p>
<ul>
<li><p>首先需要直接向目的端口发起一个N_PORT Login过程，目的协商一系列的参数</p>
</li>
<li><p>然后进行Process Login过程（类似TCP向端口发送握手包），即进行应用程序间的通信。比如FC可以承载SCSI协议，那么此时Initiator端就需要向Target端发起请求了。</p>
</li>
<li><p>这些Login过程其实就是上三层的内容，属于会话层。但是Login帧也必须通过下4层来封装并传输到目的地，就像TCP握手一样。</p>
</li>
</ul>
<p>FC网络中还有一中<strong>FC Control Service</strong>，如果节点向这个服务进行注册了以后，一旦网络状态有变动，将会把最新的信息同步到这些节点。</p>
<h4 id="最后一点"><a href="#最后一点" class="headerlink" title="最后一点"></a>最后一点</h4><p>上面提到的名称服务器、注册服务器其实一般都是运行在交换机内部的，而不是物理上的服务器。</p>
<h3 id="传输层"><a href="#传输层" class="headerlink" title="传输层"></a>传输层</h3><p>FC协议的传输层的作用与TCP相似，也也进行Segment以及通过端口号区分上层应用。</p>
<ul>
<li>对上层数据流进行Segment。<br>每个Exchange（上层程序）发来的数据包，被FC传输层分割为Information Unit，类似于TCP的Segment。<br>然后下层协议为每个Segment分配一个Sequence ID，再分割为FC所适应的帧</li>
</ul>
<ul>
<li>区分上层程序。TCP是通过端口号，而FC协议是通过Exchange ID来区分。</li>
</ul>
<h2 id="FC适配器"><a href="#FC适配器" class="headerlink" title="FC适配器"></a>FC适配器</h2><p>要构建一个完整的FC网络，除了需要FC交换机，还需要FC适配器(FC HBA,Host Bus Adapter)</p>
<blockquote>
<p>HBA可以指代任何一种设备，只要这个设备的作用是将一个外部功能接入<strong>主机</strong>总线，所以PCIE网卡、声卡和显卡都可以叫HBA。</p>
</blockquote>
<p>下图是用来接入FC网络的各种线缆，有SC光纤，DB9铜线和RJ45/47线缆。可以看出FC不一定是光纤</p>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-3a6e3b149e5a95a0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<p>FC适配器有自己的CPU、RAM、ROM。是一个嵌入式设备。与RAID卡类似，只是不像RAID卡需要那么多的RAM来做数据缓存。</p>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-c8fffe61b2207ff4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<h1 id="SCSI迁移到FC"><a href="#SCSI迁移到FC" class="headerlink" title="SCSI迁移到FC"></a>SCSI迁移到FC</h1><h2 id="如何迁移"><a href="#如何迁移" class="headerlink" title="如何迁移"></a>如何迁移</h2><p>在上面一章我们把FC协议进行了简单的介绍，现在是时候把SCSI迁移到FC上了。</p>
<p>回顾一下，为什么要这么做，因为SCSI总线只能接16个节点，不利于扩展，同时传输的距离有限，而且不够高效等。所以我们可以在主机与后端存储之间使用FC协议，把基于并行SCSI总线的存储网络架构迁移到FC的网络架构。</p>
<p>迁移的过程中存在一个问题，我们知道FC协议并没有定义<strong>SCSI指令集</strong>这样面向磁盘存储数据的通用语言。那怎么解决这个问题呢？</p>
<p>在<a href="http://www.cnblogs.com/dy2903/p/8426597.html" target="_blank" rel="noopener">【大话存储】学习笔记（13章），协议融合</a>中提到了协议融合，此时FC协议与SCSI协议有重叠，但是FC协议在某些方面可以做得更好，所以可以<strong>将SCSI语言承载于FC协议进行传送。</strong></p>
<p><strong>将连接主机和磁盘阵列的通路从并行的SCSI总线替换为串行传输的FC通路。但是盘阵后端连接磁盘的接口还是SAS接口。</strong><br><img src="http://upload-images.jianshu.io/upload_images/1323506-8ec8dbac0cf3e18a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<p>这样单台盘阵所能接入的磁盘容量没有提升，但<strong>是前端的性能</strong>提升了，因为使用FC协议，可以更为的高速。</p>
<h2 id="好处"><a href="#好处" class="headerlink" title="好处"></a>好处</h2><p>引入FC之后，带来的好处为</p>
<ul>
<li>如果一个盘阵只有一个FC接口，那么我们完全可以使用FC交换机来扩充端口。而且采用了这样的<strong>包交换</strong>架构，可以实现多个节点向一个节点收发数据，传输效率大大提升。</li>
</ul>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-f81caa59df74d8ff.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<p>这样就实现了多台主机共享一个盘阵，提升了盘阵的利用率。</p>
<ul>
<li><p>而且因为可以使用光纤，所以传输距离加长了。</p>
</li>
<li><p>FC协议功能更为丰富，可以为<strong>每台主机</strong>划分不同的LUN，保证了安全性。<br>既然所有的主机都挂在了盘阵上，怎么保证每台主机能独享一块LUN呢？可以从FC交换机，磁盘阵列控制器入手。</p>
<ul>
<li><p>在磁盘控制器上做手脚：</p>
<p>在SCSI协议中有这样一个过程，此时Initiator想要与Target要进行通信，Initiator需要发一条Report LUN指令给Target，Target端在收到这条指令以后，需要返回自己的<strong>LUN信息</strong>。那么磁盘控制器可以 LUN的时候，<strong>根据发起端的身份，提供相应的LUN给它。</strong>如果强行访问其他的LUN，就会拒绝。这种方法就叫<strong>LUN masking</strong></p>
<p>总的来说，可以把LUN当做蛋糕，磁盘控制器就是主人，他可以调查每个主机的身份，根据不同的身份来分配蛋糕。</p>
<p>注意，这是SCSI指令集的功能，只要承载了SCSI指令集的协议就可以实现这个功能。</p>
</li>
<li><p>在FC交换机上做手脚：<br>我们知道以太网交换机可以划分VLAN，也就是可以把某几个端口划分到一个逻辑上的<strong>LAN</strong>中。同样FC交换机也可以实现类似的功能，不过名字叫<code>ZONE</code>。<br>ZONE有软ZONE和硬ZONE之分。</p>
<ul>
<li><p>软ZONE：在名称服务器上做手脚，欺骗进行名称注册的节点，向他们通告其他节点信息。</p>
</li>
<li><p>硬ZONE：把交换机某端口归为一个ZONE，底层完全隔离。如下</p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-7e43db707c592a6f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<h2 id="多路径访问目标"><a href="#多路径访问目标" class="headerlink" title="多路径访问目标"></a>多路径访问目标</h2><p>如果盘阵有<strong>两个控制器</strong>，每个主机上都有两块FC适配卡，它们都连接到了FC交换机。</p>
<p>这样会存在一个问题，因为主机有两块HBA卡，而每块HBA可以识别两块LUN，所以整个主机会识别出4块磁盘，这就有问题了，因为这样磁盘就有重复了，造成了混乱。</p>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-c4eaccd2284dea41.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<p>那么你可能会说，为啥要两块FC HBA卡呢？因为一块HBA有<strong>单点故障</strong>，如果使用两块HBA卡，一旦一块HBA卡出现了故障，另一块卡依然可以维持主机到盘阵的通路。</p>
<p><strong>那多路径的问题怎么解决：</strong>可以在操作系统中安装<strong>多路径软件</strong>，它可以识别FC提交上来的LUN，向操作系统提交单份LUN。这个软件还有个作用，如果某个<strong>控制器</strong>发生故障，通过这个软件立即重定向到另一个控制器。<br><img src="http://upload-images.jianshu.io/upload_images/1323506-0ef45f1f810095a0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

        
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="en">
    <link itemprop="mainEntityOfPage" href="https://duyang2903.gitee.io/2019/11/15/%E5%A4%A7%E8%AF%9D%E5%AD%98%E5%82%A8%EF%BC%8C%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%8820%E7%AB%A0%EF%BC%89%EF%BC%8C%E4%BA%91%E5%AD%98%E5%82%A8/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="dy2903">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="dy2903的博客">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          
            <a href="/2019/11/15/%E5%A4%A7%E8%AF%9D%E5%AD%98%E5%82%A8%EF%BC%8C%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%8820%E7%AB%A0%EF%BC%89%EF%BC%8C%E4%BA%91%E5%AD%98%E5%82%A8/" class="post-title-link" itemprop="url">大话存储，学习笔记（20章），云存储</a>
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">Posted on</span>

              <time title="Created: 2019-11-15 10:48:24" itemprop="dateCreated datePublished" datetime="2019-11-15T10:48:24+08:00">2019-11-15</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">Edited on</span>
                <time title="Modified: 2019-11-13 21:27:14" itemprop="dateModified" datetime="2019-11-13T21:27:14+08:00">2019-11-13</time>
              </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>目前云计算、云存储、云备份等技术可谓是铺天盖地，其中不乏有很多是浑水摸鱼的，本来没有多少云的性质，只是打着云的旗号来炒作而已。</p>
<p>目前市场对一款产品是否是<strong>云</strong>，没有明显的界定。因为云本来就没有一个标准。</p>
<h2 id="云的是怎么来的"><a href="#云的是怎么来的" class="headerlink" title="云的是怎么来的"></a>云的是怎么来的</h2><p>国外在指代一堆设备的时候，一般使用Cluster这个词，而中文翻译一般是“簇”或者“集群”。云这个词来源已不可考，也许是某个人在讲授PPT的时候，顺口说了一句”The Servers in the cloud”的吧，这样Cloud这个词就诞生了。</p>
<h3 id="对云的几种认识"><a href="#对云的几种认识" class="headerlink" title="对云的几种认识"></a>对云的几种认识</h3><p>目前人们对云的认识基本就有4种不同的观点：云即设备、云即集群、云即IT系统、云即服务</p>
<ul>
<li><p>云即设备：</p>
<p>  这是最原始的观点，也就是所谓的云只是指代一堆设备，因为没有设备的支撑，哪来的云。</p>
</li>
<li><p>云即集群：</p>
<p>  光有设备还不行，还需要这堆设备<strong>有机</strong>的联系起来，相互协同，对外呈现为一个<strong>集</strong>群，这是在“云即设备”上的一次发展。</p>
</li>
<li><p>云即IT系统：</p>
<p>  上面说到的<strong>集群</strong>，也只是一堆服务器放在一起，可以协作，若要进一步发展，需要加上软件作为灵魂，比如某企业的IT系统。</p>
</li>
<li><p>云即服务：</p>
<p>  IT系统一般是用来支撑企业的业务的，但是我们能不能通过他来盈利呢？这就涉及到商业模式上面了。主要有如下几种模式：</p>
<ul>
<li><p>直接卖了：</p>
<p>如果像卖房子一样，受众很小，因为需要购买一整套IT系统的人很少。</p>
</li>
<li><p>租出去：</p>
<p>这就如同租房子一样，受众相对于卖房子大很多。但是盈利慢</p>
</li>
<li><p>利用IT系统来运营某种业务，用来赚钱：</p>
<p>这种方式受众更大，像邮箱、网页、博客，几乎全民都是客户，所以盈利面很大。这样看来，<strong>能提供某种形式IT服务的一整套IT系统都是云</strong>。从这个角度，所有的互联网运营商，比如各大网站，都是云运营商。</p>
</li>
</ul>
</li>
</ul>
<h3 id="给云下个定义"><a href="#给云下个定义" class="headerlink" title="给云下个定义"></a>给云下个定义</h3><p>那么云目前最主流的<strong>定义</strong>是啥？</p>
<p>上面提到过，设备组成集群，集群搭上软件称为IT系统，IT系统用来服务，好了我们可以把之前的观点结合起来下个定义：</p>
<blockquote>
<p>云是一个可<strong>运营</strong>的IT系统，</p>
</blockquote>
<p>但是这个定义缺少最关键的东西，<strong>就是资源迅速灵活地部署和回收</strong>。所以云当前最主流的定义为：</p>
<p>云是一个智能IT系统，它是：</p>
<ul>
<li><p>可运营的</p>
</li>
<li><p>可以迅速灵活部署</p>
</li>
<li><p>可迅速回收资源的</p>
</li>
</ul>
<p>也就是</p>
<blockquote>
<p>云是一个可运营的，迅速灵活部署和回收资源的智能IT系统。</p>
</blockquote>
<p>那么云应该具有如下性质：</p>
<ul>
<li><p>云提供商拥有一定规模的硬件基础（计算、存储、网络）</p>
</li>
<li><p>作为服务进行交易，而不是实物交易，客户只是<strong>租用</strong>资源</p>
</li>
</ul>
<p>也就是云其实是一种<strong>商业模式</strong>，如果认为只有底层使用了硬件集群和虚拟化技术的系统才是云这种观点是非常狭隘的。</p>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-9d350c344484f9b2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<h2 id="谁催生了云"><a href="#谁催生了云" class="headerlink" title="谁催生了云"></a>谁催生了云</h2><p>谁催生了云？当然是<strong>需求</strong></p>
<h3 id="传统IT的问题"><a href="#传统IT的问题" class="headerlink" title="传统IT的问题"></a>传统IT的问题</h3><p>互联网以及智能终端的普及，让信息得到了爆发性的增长，那么对IT基础架构（计算、存储、网络）来说，正在快速被饱和。</p>
<p>我们可以看看传统IT怎么运作的？比如运营商部门分析出网页游戏业务会有20%的增长，所以需要扩容，比如增加Web服务器、数据库服务器、存储系统的数量或容量，然后需要采购设备，遵循一系列的流程，这样周期非常的长，甚至慢于业务的变化周期。</p>
<p>但是另外一个部们的在线视频业务因为业绩不好，利用率不足60%。</p>
<p>当然最原始的想法是将在线视频业务的的40%余量分配给网游部门，不过会存在大量的技术风险。比如两种业务部署在同一个操作系统，会增加业务的粘度，不利于运维，然是如果把业务部署在不同的服务器上，更不利于运维。</p>
<p>加上现在数据中心中存在不同的协议、不同厂商的设备，如果靠手动来部署、管理和回收资源，效率低而且容易错，业务上线的速度也不快。</p>
<p>我们总结一下，传统的IT系统存在三个问题：</p>
<ul>
<li><p>业务部署周期长</p>
</li>
<li><p>资源不能充分回收利用，存在孤岛</p>
</li>
<li><p>手动部署无法满足需求。</p>
</li>
</ul>
<p>这就痛点。</p>
<h3 id="云其实是商业模式"><a href="#云其实是商业模式" class="headerlink" title="云其实是商业模式"></a>云其实是商业模式</h3><p>不过上面的说法只是云诞生的一部分理由，实际上最初的云，实际是一种商业模式，当商业模式与计算机技术结合之后，才产生了云这个代名词。这也是云没有外在的像技术一样严格的标准的原因。<br><img src="http://upload-images.jianshu.io/upload_images/1323506-20923223647d8eda.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<h2 id="系统架构变化"><a href="#系统架构变化" class="headerlink" title="系统架构变化"></a>系统架构变化</h2><p>要解决之前提到的业务部署周期长，无法实现自动化，资源不能方便的回收和复用等，最容易想到的技术手段自然是<strong>虚拟化。</strong></p>
<p><strong>服务器虚拟化</strong>，即虚拟机系统，充分利用了资源，再加上Vmotion,DRS(Distrubted Resource Scheduler)等技术，极大的增加了部署灵活性和资源均衡性。</p>
<p>我们来看看部署了虚拟机以后对之前的问题带来的变化。</p>
<ul>
<li><p>资源充分利用问题：旧业务余量会自动回收，新业务所需的应用可以直接以虚拟机的形式部署在物理机，因为操作系统各用各的，粘合影响得以避免。</p>
</li>
<li><p>上线业务周期长的问题：部署虚拟机消耗的时间比物理机少了很多，上线速度加快</p>
</li>
<li><p>手动部署问题：使用一种资源自动化分配和回收平台来解决自动化部署问题。</p>
</li>
</ul>
<p>那么所谓<strong>虚拟化</strong>，其实就是在传统的数据中心上加上一个<strong>弹性层</strong>，这样整个数据中心就变成了软数据中心了。</p>
<p>如果还能做到<strong>部署回收自动化、可度量化、服务化、可运营的数据中心</strong>，则就是一个云数据中心了。</p>
<p><strong>综上所述</strong>，云系统中重要的角色有：</p>
<ul>
<li><p>虚拟化</p>
</li>
<li><p>集群化</p>
</li>
<li><p>自动化：实现资源自动部署、调度、分配、回收的管理者</p>
<ul>
<li>对内可以与其他组件进行通信，管理资源</li>
<li>对外可以响应业务部署的需求，并且将这些需求转化为对内的资源调度<br>这个模块综合起来就是“自动化”。</li>
</ul>
</li>
<li><p>可度量化：<br>  也就是用户用了什么资源，为期多少时间，耗费多少成本，毛利率几何，报价几合可以精确度量、定价。</p>
</li>
</ul>
<p>纵观云发展的过程中，说不清到底是先有云这种商业模式还是先有云这种技术架构的，两者其实是相互催生、相辅相成。</p>
<p>回顾存储系统的技术发展过程。</p>
<ul>
<li><p>最开始的时候，存储系统只需要关心数据存储，只要提供一块空间，怎么管，怎么用，底层是不关心的，</p>
</li>
<li><p>后来，存储系统开始注重数据管理，开发了诸如快照、重删、容灾等功能。</p>
</li>
<li><p>再后来，又到了<strong>数据运营</strong>阶段，还关心数据怎么<strong>用</strong>的问题，此时需要更贴近用户的应用，注重业务展现。</p>
</li>
</ul>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-da89c6f90b4fe2b9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<h2 id="公有云和私有云"><a href="#公有云和私有云" class="headerlink" title="公有云和私有云"></a>公有云和私有云</h2><p>现在我们已经有了一个云化的数据中心了，那么可以按照数据中心的是对企业内部开放服务还是给任何人开放服务来分为私有云和共有云：</p>
<blockquote>
<ul>
<li>私有云：数据中心对企业内部开发，提供云服务，比如存储空间申请、企业应用系统的快速部署等。</li>
</ul>
</blockquote>
<blockquote>
<ul>
<li>公有云：对外营业，通过互联网提供各种云服务。</li>
</ul>
</blockquote>
<ul>
<li><p>私有云让企业IT部门角色转变</p>
<p>  传统的IT部门是一个支撑部门，始终处于业务部门的牵引之下，所有的采购、经费申请必须以业务需求为前提。</p>
<p>  那么怎么提升IT部门的地位，只要也得与业务部门处于平等的地位。云中的“服务”两字正好满足了这种需求，比如IT部门可以通过建立规范的资源申请流程，然后建立电子工单审批系统，只有通过审批以后才提供对应的服务。还可以统计某个部门在某段时间内使用了多少IT资源，消耗了多少成本。</p>
<p>  这样IT部门成为一个独立的服务角色，其他部门向IT部门申请资源的时候，是以<strong>协商的态度</strong>而不是强势的牵制的态度，而且因为资源可度量了，IT部门可以做出合理的预测，申请后续经费等资源变得更有说服性。</p>
</li>
<li><p>公有云受制于互联网带宽发展</p>
<p>  如今互联网的接入速度还是比较低的，大量用户的速度还是1Mbps，也就是只有100KB/s的吞吐量的接入速度。此时，若给他一个iSCSI协议访问的存储空间是不现实的，最多提供网盘这样的上传下载服务。</p>
<p>  常用的SaaS服务（网页、聊天、视频、网盘等）基本上可以基于低速网络，但是IaaS就困难了，比如访问虚拟机的时候，如果不是用xshell这种方式，而是使用虚拟桌面登录，1Mbps非常勉强。而且，如果要安装软件，还得把安装包传上去。</p>
</li>
</ul>
<p>综上所述，云目前最能被广泛推进的地方就是<strong>新建数据中心</strong>，企业兴建私有云，运营商兴建混合云<br><img src="http://upload-images.jianshu.io/upload_images/1323506-dc5151c056d699f9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<h2 id="云系统架构及组成"><a href="#云系统架构及组成" class="headerlink" title="云系统架构及组成"></a>云系统架构及组成</h2><p>下图为云具体的架构：<br><img src="http://upload-images.jianshu.io/upload_images/1323506-bd33673f970baa39.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"><br>分为如下几个层次</p>
<ul>
<li><p>物理架构层：比如供电、散热等</p>
</li>
<li><p>基础IT架构层：包括网络、存储、服务器等</p>
<p>  需要注意的是这些服务器与存储设备不是孤岛，他们会组成集群，上面搭载虚拟化，并进行自动化的管理。</p>
</li>
<li><p>基础架构/集群管理层</p>
<p>  有了集群还不够，需要在上面覆盖虚拟化层来增加系统的<strong>弹性</strong>。</p>
<p>  对于服务器就是VMware这样的虚拟机平台。对于存储，就只能分布式文件系统或者分布式卷管理系统才能满足这种需求。</p>
</li>
<li><p>资源部署层：</p>
<p>  现在我们已经可以得到一个网络、服务器、存储的集群，还需要一个<strong>用来管理和驱动</strong>集群的角色。</p>
<p>  比如VMware的Vsphere可以进行计算资源的包裹，分布式系统可以进行存储资源的包裹。</p>
<p>  利用VSphere提供的Vmotion与DRS可以将虚拟机在集群节点中灵活移动，自动资源动态分配和回收。</p>
</li>
<li><p>中间件层</p>
<p>  应用层与资源层需要一个中间层来适配，这就是中间件层</p>
</li>
<li><p>应用引擎层</p>
<p>  这一层需要提供一个通用的业务开发平台，可以实现统一发布。</p>
</li>
<li><p>业务展现与运营层</p>
<p>  现在数据中心的架构已经具有<strong>集群化、虚拟化、自动化</strong>的形态了，但是这只是对自己有用，对用户来说，他们不用关心底层用不用集群或者虚拟化，只关心是否能<strong>得到快速的服务和响应</strong></p>
<p>  所以我们还需要一个业务展现界面，这就是云服务。</p>
</li>
</ul>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-f801063b142affbc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<p>那么出租数据中心其实可以在以下几个层次中进行：</p>
<ul>
<li><p>基础设施即服务（IaaS）</p>
<p>  所谓<strong>基础设施</strong>指的是云系统中的硬件设施如服务器、网络、存储。所以IaaS只是提供硬件平台，具体的计算任务由用户自行部署。</p>
<ul>
<li><p>如何卖存储空间：</p>
<p>可以有多种方式，比如卖裸空间、文件存储空间等。</p>
</li>
</ul>
<p>  <strong>裸空间</strong>就是最终用户看到的是一块硬盘，所有协议当然首选ISCSI，以便跨越IP网络，这样用户可以通过ISCSI Initiator连接云提供商的ISCSI Target，然后就可以获得多个LUN。</p>
<p>  对于云中存储系统，<strong>精简重删</strong>这些特性应该是必须的，可以降低不必要的空间占用，而动态分级可以进一步节省存储成本。</p>
<ul>
<li><p>如何卖服务器、虚拟机</p>
<p>虚拟机平台需要考虑几种功能：<br>一是动态迁移，即虚拟机可以在不影响应用系统的情况下在物理机之间进行迁移。  </p>
<p>二是资源动态分配调度， </p>
<p>三是管理方便。</p>
<p>Amazon在IaaS提供两个产品：弹性计算云（Elastic Compute Cloud , EC2）和简单存储服务(Simple Storage Service ,S3)，分别对应了主机计算集群和存储集群</p>
</li>
</ul>
</li>
<li><p>平台即服务</p>
<p>  相对于IaaS，PaaS屏蔽而不出租基础架构，转而出租更高一层的软件平台。用户可以通过这个平台制作应用。因为这个平台是一种运行与硬件集群中的软件，用户实际上相当于租用了计算业务。</p>
</li>
<li><p>软件即服务</p>
<p>  SaaS是云服务中的最外层，直接出售业务级别的内容。比如Web网页等。</p>
</li>
</ul>
<h2 id="实例说云"><a href="#实例说云" class="headerlink" title="实例说云"></a>实例说云</h2><p>下面使用3Tera Applogic的例子来说一下IaaS层</p>
<p>3Tera的IaaS平台名为Applogic，是一不可以实现IaaS功能的软件虚拟化平台。我们可以看一下它的底层架构：</p>
<p>主要分为4大层次：</p>
<ul>
<li><p>硬件层：</p>
<p>  本层包含服务器、存储、网络设施等。</p>
<p>  Applogic不要求底层存储必须是基于SAN的，可以是本地IDE。若干服务器通过千兆以太网连接起来，形成集群。</p>
<p>  然后在这个有限且分配不灵活的资源池上，实现一种管理方便、使用方便、资源灵活分配的虚拟化层。</p>
</li>
<li><p>分布式核心虚拟化层(Applogic OS)：</p>
<ul>
<li><p>计算虚拟化：Distributed Virtual Machine Manager（DVM）</p>
<p>本层的核心是虚拟机技术，通过Hypervisor引擎来虚拟化成多个主机，比如说VMware的ESX Server就是实现这个目的的。只不过Applogic使用的是Xen虚拟机平台。</p>
</li>
<li><p>存储虚拟化：Global Volume Store(GVS)子层：</p>
<p>Applogic使用的是自研分布式文件系统，在这个文件系统之上虚拟出Volume，而且Volume可以Mirror、Clone、Snapshot等。</p>
<p>每个Volume在多个物理主机上有镜像以解决HA问题，并且可以提升读性能。<br>而这些Volume对于最终的虚拟机就是裸磁盘，在这个虚拟化层上，每个节点将自己的本地存储空间贡献出来，所有节点的存储被整合起来进行虚拟化。</p>
</li>
<li><p>网络资源虚拟化：Logical Connection Manager(LCM):将物理网络搞成虚拟网络</p>
</li>
</ul>
</li>
<li><p>一次性基础设施虚拟层</p>
<p>  所谓一<strong>次性基础设施</strong>，其实就是虚拟机可以按需创建。每个应用程序可以分配一个独立基础设施，包括防火墙、负载均衡、Web服务器、数据库服务器等。当要删除应用程序的时候，可以直接把虚拟机删除了。</p>
<p>  这些角色可以虚拟成一个个对象，在图形界面使用鼠标拖拽的方式建立对象<br><img src="http://upload-images.jianshu.io/upload_images/1323506-a090957e0a02163a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<p>  上图创建了一个防火墙、负载均衡、2台Web防火墙、数据库服务器，整个网格中的Volume按照Application进行隔离，不同的Application只能看到自己的Volume。</p>
<p>  防火墙、负载均衡、WebServer之间互联的IP用户不需要关心，系统<strong>自动分配</strong>，唯一需要配置的是整体Application的IP地址信息。</p>
</li>
<li><p>网络控制层和应用程序管理层</p>
<p>  以Application为单位向用户交付。</p>
</li>
</ul>
<p>Applogic带来的革命是把复杂的底层硬件变得简单，通过拖拽对象来状态自己的基础架构，最终以适合某中Application运行的整体服务器&amp;存储&amp;网络来交付。</p>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-3b7d15e618b11a68.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<h2 id="云的缺点"><a href="#云的缺点" class="headerlink" title="云的缺点"></a>云的缺点</h2><p>在看云的缺点之前先看一下云的优点：</p>
<ul>
<li><p>避免资源的浪费：</p>
</li>
<li><p>节能</p>
</li>
<li><p>角色转变</p>
</li>
</ul>
<p>存在的问题：</p>
<ul>
<li><p>稳定性和安全性：如何解决两个存储资源互通的问题，如何才能保证完全隔离。</p>
</li>
<li><p>平台迁移<br>  怎么样才能在不影响业务的前提下迁移到云平台上。</p>
</li>
<li><p>不兼容的问题：不同云服务商提供的架构不同，接口也不同。</p>
</li>
</ul>
<h2 id="云之后的发展"><a href="#云之后的发展" class="headerlink" title="云之后的发展"></a>云之后的发展</h2><h3 id="云的本质"><a href="#云的本质" class="headerlink" title="云的本质"></a>云的本质</h3><p>云本质是一种服务，而不是一种物质，正因为此，它必须基于物质才能显示功效，《易经》有云：“形而上者谓之道，形而下者谓之器”。所以下器者，谓之服务器+存储+部署管理软件；上道者，谓之“云”。所以云是一种道，是一种方式和方法，而不是某种设备，某个软件，当然云需要由硬件+软件来承载而已。</p>
<p>所以，<strong>云和速度性能没有直接关系</strong>。云本身不一定就是一个高速高冗余的东西，而是说底层硬件一般使用并行计算集群和存储集群，在这个基础上，云才能表现出更大的效能。</p>
<p>而且云也不是为了提速而生，<strong>它的主要目的是廉价高效的利用资源并降低硬件的应用成本和管理成本。</strong></p>
<p>其实云早就存在了，只有近两年才被炒作起来，互联网服务器就是云服务，所以有人提出IT服务即云，Everything as a service。</p>
<p>其实在40年前，我们还是用集中分时计算，随后到了世纪相交的纪念，用户各自购买基础架构进行计算和存储，然后又逐渐回到了集中计算的时代，实际上这既不是进化，又不是退化，是“分久必合，合久必分。万物皆在轮回中不断发展，到一定程度就回到当初的形态，但是承载它的物质是连续不断的提升的。所轮回的只是其上的那层能量，谓之道。</p>
<h3 id="Micro、Mini、Normal、Huge、Grid弹性数据中心"><a href="#Micro、Mini、Normal、Huge、Grid弹性数据中心" class="headerlink" title="Micro、Mini、Normal、Huge、Grid弹性数据中心"></a>Micro、Mini、Normal、Huge、Grid弹性数据中心</h3><p>弹性核或者软数据中心：将若干刀片与高密度的磁盘柜以及微型交换机打包到一个或者几个机柜里面，再覆盖以弹性层，比如虚拟机管理系统以及分布式存储系统，将这样一个微型弹性软核心做为一个可提供IaaS服务的整体交付给用户。</p>
<p>或者再在这个软核上覆盖一层业务展现于管理层，直接交付到SaaS层。一柜或者数柜交付的弹性基础设施，可以称为Micro Cloud</p>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

        
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="en">
    <link itemprop="mainEntityOfPage" href="https://duyang2903.gitee.io/2019/11/15/%E5%A4%A7%E8%AF%9D%E5%AD%98%E5%82%A8%EF%BC%8C%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%8818%E7%AB%A0%EF%BC%89%EF%BC%8C%E6%95%B0%E6%8D%AE%E5%89%8D%E5%A4%84%E7%90%86%E5%92%8C%E5%90%8E%E5%A4%84%E7%90%86/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="dy2903">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="dy2903的博客">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          
            <a href="/2019/11/15/%E5%A4%A7%E8%AF%9D%E5%AD%98%E5%82%A8%EF%BC%8C%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%8818%E7%AB%A0%EF%BC%89%EF%BC%8C%E6%95%B0%E6%8D%AE%E5%89%8D%E5%A4%84%E7%90%86%E5%92%8C%E5%90%8E%E5%A4%84%E7%90%86/" class="post-title-link" itemprop="url">大话存储，学习笔记（18章），数据前处理和后处理</a>
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">Posted on</span>

              <time title="Created: 2019-11-15 10:48:24" itemprop="dateCreated datePublished" datetime="2019-11-15T10:48:24+08:00">2019-11-15</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">Edited on</span>
                <time title="Modified: 2019-11-13 21:27:14" itemprop="dateModified" datetime="2019-11-13T21:27:14+08:00">2019-11-13</time>
              </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>存储其实就是一台主机，上面也运行着各种各样的应用程序，可以在原本的裸数据之上实现更高级的功能，实现更多的附加值。现在的高端存储越来越开发，比如EMC 的 V-MAX，高端存储也用普通的x86了。</p>
<p>存储系统有两大功能：数据存储和数据管理。</p>
<ul>
<li><p>数据存储：控制器、磁盘、HBA卡等，主要是提供<strong>裸数据</strong>存储服务。</p>
</li>
<li><p>数据管理：分层、快照、克隆等高级功能。又可把数据管理部分分为对数据的<strong>前处理和后处理</strong></p>
<ul>
<li><p>前处理：数据未放入磁盘之前的初加工，或者对存放空间做预先准备，比如精简、重删</p>
</li>
<li><p>后处理：数据写入磁盘之后，再将数据读出来进行处理。比如数据迁移。</p>
<p>有些功能既有前处理的过程，又有后处理的过程。比如快照，快照的生成是后处理，但是生产后，每个IO会Copy on Write，这就是典型的前处理。</p>
<p>所以存储除了比主机多运行了一些更强大更复杂的功能之外，其他与主机无异，比如快照、重删、镜像、复制等。</p>
</li>
</ul>
</li>
</ul>
<h1 id="Thin-Provision"><a href="#Thin-Provision" class="headerlink" title="Thin Provision"></a>Thin Provision</h1><h2 id="超供的模式"><a href="#超供的模式" class="headerlink" title="超供的模式"></a>超供的模式</h2><p>精简也即<code>Thin Provision</code>，但是精简这种翻译故弄玄虚，不如叫<code>超供(Over Allocation)</code>最能反映本质。</p>
<p>我们知道申请一个3G的网络硬盘，供应商不会真的提供3GB的空间，它只是记录一下，只有真的塞入了3GB的数据，才会占用这么多空间。</p>
<p>这是怎么办到的？因为不是每个人都会把自己的空间用完，如果前面先把空间分配出去了，又一直没有人占用，空间上就有浪费。这样系统其实可以在后台悄悄的把空间分配给其他的客户端，相当于对客户端进行<strong>欺骗</strong>。</p>
<p>这种方法其实非常常见，比如说在银行存钱10000块，银行不会一直给你保留那么多钱，而是会把钱偷偷的拿来放贷。这是因为不是每个人都会立刻取钱的，完全可以拆东墙补西墙。</p>
<p>总结一下，所谓<code>超供</code>，就是指分配给你的空间是虚的，只有在实际用到的时候才占用空间。所以存储系统需要实时监控物理空间的使用情况，一旦到了临界值，则需要扩容。</p>
<p>要实现超供，NAS系统较容易实现，因为NAS系统是自己维护文件与物理空间的对应关系的。但是如果存储系统提供的是<strong>块</strong>，因为文件与物理空间的映射其实是由更上层的文件系统维护的，存储系统本身是感知不到的。</p>
<p>那么Thin Provision是怎么实现的呢？</p>
<ul>
<li><p>如果存储系统使用文件系统的思想：</p>
<p>  文件系统中有一种<code>稀疏文件，Sparse File</code>，它的作用是在向文件中写入大量的<code>0</code>的时候，实际上只在<strong>内存</strong>上生成这些0，只是在真正需要的时候才分配空间。</p>
<p>  所以只需要对Spare File进行修改，然后把LUN设置为一个Sparse File就可以了。</p>
</li>
<li><p>如果存储系统不是使用文件系统的思想</p>
<p>  我们自然需要单独维护一张<strong>逻辑地址与物理地址的映射表</strong>，可以以连续条带做为单位来进行扩充。</p>
<p>  问题就是随着时间的推移，有可能会出现逻辑上连续的条带但是在物理上却不连续的情况，所以大块连续的IO却变成了随机IO，效率自然低下。</p>
</li>
</ul>
<h2 id="Thin-Provision对性能的影响"><a href="#Thin-Provision对性能的影响" class="headerlink" title="Thin Provision对性能的影响"></a>Thin Provision对性能的影响</h2><p>Thin Provision对性能的影响主要在：耗费额外的CPU周期、物理空间碎片上。</p>
<ul>
<li><p>额外的CPU周期：</p>
<p>  收到一个读IO，需要查Bitmap看读IO的目的地址是否已经分配了空间，如果没分配，则需要返回应全0x00，同样对写IO，则需要查目的地址是否被写过，如果被写过的话，还需要查找其他的空间。多了很多的步骤，而且还需要维护元数据，对计算资源消耗比较大。</p>
</li>
<li><p>物理空间碎片：</p>
<p>  因为Thin是随用随分配，如同操作系统对内存的管理一样，则一定会产生碎片的，不样连续的空间可能被多个LUN占用，活生生的把连续IO变成了随机IO，效率自然降低。</p>
</li>
</ul>
<p>要实现Thin的核心模块，只要有三大元数据就够了：位图、表、树。</p>
<ul>
<li><p>位图：记录底层连续物理空间那些分配了，哪些未被分配。</p>
</li>
<li><p>表：记录LUN逻辑地址与物理地址的对应关系。因为逻辑地址已经不于传统的物理地址一一对应了。这张表需要按照逻辑地址进行排序，以便于查询。</p>
</li>
<li><p>树：在内存中生成，用于迅速的查询表的结构。</p>
</li>
</ul>
<p>比如使用64b的地址长度， 分配粒度32KB，也就是说每32KB的物理块就用一个64b的地址进行表示。因为表代表了逻辑与物理地址的对应关系，所以表的每一项条目大小就是128b。对于100TB来说，对应的表的容量为$(100TB/32KB)*128b=512MB$，如果使用1MB的块粒度，则元数据降为16MB/TB，差别还是很大的。</p>
<p>而且元数据这么大，不可能全部放到内存里面，所以又会牵扯到读写磁盘，性能严重下降。</p>
<h2 id="Thin-Provision脆弱性"><a href="#Thin-Provision脆弱性" class="headerlink" title="Thin Provision脆弱性"></a>Thin Provision脆弱性</h2><ul>
<li><p>对性能影响太大：</p>
<p>  有些厂商的产品，开启了Thin功能，性能降了70%，而粒度与性能总是一对矛盾，为了性能而增加粒度，就会丧失Thin的意义。</p>
<p>  Thin还会引入碎片的问题，所以需要进行碎片整理，与文件系统的碎片整理不同，LUN碎片整理指的是把分配到不同的RAID组上的碎片进行整理，而文件系统碎片整理指的是对LUN内的逻辑上文件碎片进行整理。</p>
</li>
<li><p>效果很难维持：比如说在文件系统再进行了碎片整理，它会读出零散的碎片，合并以后写到新的位置，对Thin LUN来说，又需要重新分配新位置。比如100GB的LUN上有50GB的碎片，现在Thin LUN可能只分配了70GB物理空间，进行<strong>文件系统</strong>碎片整理以后，读出50GB的碎片，发现还需要30GB空间，这样反而把之前没有分配的30GB重新分配掉了。</p>
<p>  再比如有些应用程序会生成大量的临时文件，结束以后就删除了，但是实际上底层LUN无法感知到，而且已经分配出去了，就没法回到原来了。</p>
<p>  综上，Thin Provision其实很脆弱，真的要不反弹的瘦，需要从应用层业务层入手，杜绝垃圾的产生。<br><img src="http://upload-images.jianshu.io/upload_images/1323506-23417ce5aa268c69.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
</li>
</ul>
<h2 id="LUN-Space-Reclaiming"><a href="#LUN-Space-Reclaiming" class="headerlink" title="LUN Space Reclaiming"></a>LUN Space Reclaiming</h2><p>比如存储只有1TB的空间，多个客户端的LUN分布在上面，现在只剩下了500GB，此时如果谁还需要500GB的LUN空间做某程序的TMP空间，则管理员只要把所有空间都给它。但是程序运行完毕以后，临时文件已经删除，但是因为这些空间之前已经分配了，所以无法再次利用。</p>
<p>若通过缩小LUN来解决这个问题，需要消耗太多的资源，那么有其他的方法么？</p>
<ul>
<li><p>存储可以自动识别对应的文件系统，当然就知道那些空间可以回收了，但是实际上目前没有产品进行尝试，因为主机端的文件系统多种多样，就算同一种系统，内核版本不同差别也蛮大的。而且，主机端文件系统是有<strong>缓存</strong>，如果存储端擅自回收空间的话，可能造成数据不一致。</p>
</li>
<li><p>存储系统自动识别0x00然后删除他们：</p>
<p>  文件系统在删除文件的时候，只是把文件从元数据中抹掉，如果再加一步，将占用的Block写入0x00的话，那么存储系统可以定期扫描LUN，发现大片连续的0x00，则回收空间。这种技术叫<code>Zero Detection</code>。缺点是，每次删除文件的时候，都需要写入大量的0进行战场的清扫，耗费的资源是极不划算的。</p>
<p>  不过这种方法在特定的场景比较有用，比如VMware在新建虚拟机的时候，需要大量写0，先把空间占住，这样做的目的是看看存储系统能提供的空间是否够用。所以可以使用这种<code>Zero Detection</code>把连续的0x00的空间回收掉。再比如Oracle数据库也有大片大片的0x00，通过这种方式也可以节省空间。</p>
</li>
<li><p>主机端通过API通知存储系统。</p>
<p>  在主机端运行一个代理程序，定期扫描剩余空间并将对应信息返回存储控制器。类似与SSD的Trim技术，几乎所有的SSD厂商都有空间回收专用程序。</p>
</li>
</ul>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-bcc64eec94fa3921.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<h1 id="分级"><a href="#分级" class="headerlink" title="分级"></a>分级</h1><h2 id="分层存储管理的意义"><a href="#分层存储管理的意义" class="headerlink" title="分层存储管理的意义"></a>分层存储管理的意义</h2><p><img src="http://upload-images.jianshu.io/upload_images/1323506-9efd2a107ec96778.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<p>我们知道对存储介质而言，性能与价格是不可兼得的。上图就表现得很明显，对于Cache ，RAM速度快，但是价格高，而且是易失的，也就是一掉电啥就没有了。</p>
<p>存储介质到了磁盘这一层，又到了个质变点，磁盘之下的虚拟磁带库、磁带都是不可随机访问的，只能当做离线存储来用。而虚拟磁带库之所以称为<strong>近线存储</strong>，是因为从在线存储将数据迁移到离线存储之后，一旦短时间内需要再次访问，需要忍受非常低的速度，而虚拟磁带库可以把数据快速提取出来，<strong>虽然仍然不可以随机存取而已。</strong></p>
<p>所以数据分级意义在于，将<strong>访问频繁、性能要求高的数据</strong>放在性能高的磁盘或者RAID组里面，不经常访问的数据移到低端硬盘里面去。这样就可以物尽其用。</p>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-29bc778c574a6338.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<h2 id="数据分级的具体形式"><a href="#数据分级的具体形式" class="headerlink" title="数据分级的具体形式"></a>数据分级的具体形式</h2><ul>
<li><p>手动、自动、实时自动分级</p>
<p>  顾名思义，手动分级需要用户自行迁移数据，而自动分级很大程度代理了用户本身，只需要提前设置<strong>规则</strong>，由分级引擎扫描元数据，一旦符合条件，则触发迁移任务。</p>
<p>  实时自动分级指的是数据写入的时候，分级引擎实时将数据重定向到对应目标。</p>
</li>
<li><p>文件级分级和块级分级</p>
<p>  文件级分级可以做到更细化策略，比如可以根据扩展名、访问频率等属性来进行分类。而且数据迁移到其他的Tier以后，原始的Tier上需要保持一个指针，目的是不影响用户的使用，因为用户程序是不会感知道文件实体放在哪里，它只需要知道文件的<strong>路径</strong>就可以了。</p>
<p>  基于块级别的数据分级所能使用的触发条件就少很多了，比如根据整个LUN或者某些Block的访问频度来进行迁移，因为块级别无法感知道上层文件逻辑。</p>
</li>
<li><p>主机端分级和存储端分级</p>
<p>  主机可以同时连接到多个外部存储上，所以如果在主机上分级可以实现数据在不同的外部存储上迁移。一般来说，需要在主机端上安装<code>代理软件</code>来监视和管理。</p>
<p>  存储系统的数据分级只能将数据在自身不同的Tier上迁移， 是完全对主机端透明的。</p>
</li>
<li><p>应用级分级和底层级分级</p>
<p>  针对于应用系统，比如数据库软件催生了专门的数据管理工具，比如对数据进行容灾、分级迁移。</p>
<p>  运行在主机端的数据分级管理程序则以普适为原则，针对任何文件、LUN进行迁移。</p>
</li>
</ul>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-b64d1f5a73ea0c04.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<h2 id="怎么判断热点数据"><a href="#怎么判断热点数据" class="headerlink" title="怎么判断热点数据"></a>怎么判断热点数据</h2><p>一般利用<strong>二八原则</strong>，把数据按照单位时间内被IO次数来进行排序，访问次数最多的20%数据为<strong>热数据</strong></p>
<h2 id="块级自动分级的底层数据结构"><a href="#块级自动分级的底层数据结构" class="headerlink" title="块级自动分级的底层数据结构"></a>块级自动分级的底层数据结构</h2><p>自动分级存储一般需要追踪每个块的<strong>属性</strong>，比如最后访问时间、某段时间内访问了多少次等数据。保存的这些数据有两种方法：</p>
<ul>
<li><p>每个块里的首或者尾追加部分空间来存放这些元数据，这就是<strong>带内元数据法</strong></p>
</li>
<li><p>单独构建一个小型数据库来存放所有块的元数据，这个数据库的数据存放在一个单独的空间，这就是<strong>带外元数据法</strong></p>
<p>  对于<strong>带内元数据法</strong>，系统即使是读，也会更新元数据块，而且分布在磁盘各处，性能问题严重。一个解决方法是使用<strong>日志</strong>，将要更新的东西记录在日志里面，在不繁忙的时候进行重放，这种方法注定要频繁的IO操作，极其浪费资源。</p>
<p>  <strong>带外元数据法</strong>更符合常理，不需要对数据块做任何结构改变，可以使用独立的软件模式来交付。</p>
</li>
</ul>
<p>集群、分布式文件系统天生就是自动分级的坯子，因为本来一个文件或者一个LUN的不同部分就可以放到不同的位置上，只需要在上面进行一些开发就可以很容易的实现分级。</p>
<h2 id="对性能的影响"><a href="#对性能的影响" class="headerlink" title="对性能的影响"></a>对性能的影响</h2><p>与 Thin Provision一样，分块粒度越小，性能损失越大。</p>
<ul>
<li><p>分块越小，元数据量大量增加，搜索和处理效率降低。</p>
</li>
<li><p>而且分级之后的数据块在物理上不连续了，增加了寻道操作，降低了性能。</p>
</li>
</ul>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-ad949c38a020a603.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<h1 id="Deduplication（重删）"><a href="#Deduplication（重删）" class="headerlink" title="Deduplication（重删）"></a>Deduplication（重删）</h1><p>不同机器的本地存储里面有若干文件，如果这些文件存在重复，每次备份自然有很多的相同部分，比较浪费空间，有没有办法来解决：</p>
<p>在开始讲解决方法之前，我们可以先总结一下出现重复可能的场景：</p>
<ul>
<li><p>同一主机或者不同主机的本地存储的重复文件</p>
</li>
<li><p>不同主机在同一NAS或者同一块存储上的重复文件</p>
</li>
<li><p>虚拟机磁盘镜像文件的重复部分</p>
</li>
<li><p>虚拟机下裸磁盘映射模式的重复部分<br><img src="http://upload-images.jianshu.io/upload_images/1323506-040f7a2cbccea364.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<h2 id="SIS的缺陷"><a href="#SIS的缺陷" class="headerlink" title="SIS的缺陷"></a>SIS的缺陷</h2><p>传统的解决方案是<strong>Single Instance Storage（SIS，单一实例存储）</strong>，可以相同内容的<strong>文件</strong>在系统中只存在一份实体，其他副本只作为指针链接而存在。注意这种技术只能避免相同内容的文件，所以只能解决同一主机里的重复文件以及连接多主机的NAS设备上的重复文件。</p>
</li>
</ul>
<p>但是对于多台主机连接到同一块存储这种场景，因为块存储对每一台主机提供不同的LUN，所以就类似于不同主机的本地存储有重复文件一样，所以依然是无能为力的。</p>
<p>我们知道虚拟机的镜像其实就是一堆文件而已，但是这些文件不大可能在每个字节上都相同，即使是安装的同一种操作系统，但是安装的应用当然是不同的。所以SIS对这种场景也无能为力。</p>
<p>最后一种情况，根本看不到文件，当然也不能实现重删。</p>
<p>SIS可以理解为<strong>文件级别的重删</strong>，不能解决所有场景的问题。而且在底层实现上也有极大的局限性，比如只能以整个文件作为对比，对于那种大部分相同但是有细微差别的文件就没办法处理了。</p>
<p>所以<strong>块级别的重删</strong>才是有意义的。可以直接比对Block的内容，消除多个副本，在元数据中只留一个<strong>指针</strong>来指向唯一一份实体即可。</p>
<p>dedup与压缩有什么区别？压缩只是局部上进行处理，而Dedup可以实现全局数据的重删。</p>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-f1f66c109e142cf8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<h2 id="核心技术——HASH"><a href="#核心技术——HASH" class="headerlink" title="核心技术——HASH"></a>核心技术——HASH</h2><p>重删用到的关键技术就是HASH算法。在<a href="https://www.cnblogs.com/dy2903/p/8426859.html" target="_blank" rel="noopener">数据库（三），底层算法</a>中我们已经说了Hash算法之神奇。下面再简单的介绍一下它的应用场景。</p>
<p>我们知道每个人的指纹各不相同，于是可以通过比对指纹就可以确定是否是同一个人留下的。同理，如果给每个Block录一个指纹，就可以快速比对出这两个块是否是完全一样呢。</p>
<p>那么生成数据指纹的有一种很好的算法，就是<strong>HASH</strong>。它又衍生出MD5(Message Digest v5)和SHA-1(Secure Hash Algorithm v1)。</p>
<p>这些算法的特点在于</p>
<ul>
<li><p>不管数据有多长，只要不超过额定大小，经过计算以后，一定可以得到一个<strong>固定</strong>长度值，比如SHA-1对一段小于264的数据进行计算以后，可以得到一个长度为160的值。</p>
</li>
<li><p>同时相同的数据经过HASH以后，总会得到相同的<strong>指纹</strong>。</p>
</li>
<li><p>而且这种HASH方法是<strong>不可逆</strong>的，也就是说通过指纹不能算出原来的值是多少。</p>
</li>
</ul>
<p>HASH算法有很多的应用。</p>
<ul>
<li><p>应用一：因为HASH以后的值不能被逆算出，所以我们完全可以将其用于登录密码保存上，这样即使黑客将密码HASH以后的值拦截到了，依然无法逆算出原来的密码。</p>
<p>  那么你可能要问，用户正常登录的时候如何匹配呢？这个时候，只要我们在后端的数据库里面依然存放密码的HASH以后的值即可，只要密码HASH以后的值与数据库中存放的对应内容匹配，则认证成功。</p>
</li>
<li><p>应用二：还有就是<strong>听歌识曲</strong>的功能，比如录制的一段曲子传到服务器上，服务器就可以告诉你这段曲子的名称。实际也就是根据曲子的音调生成指纹，然后于数据库大量的标本进行匹配，发现类似的歌曲返回名称即可。</p>
</li>
<li><p>应用三：判断数据传输的时候是否在内容上发生了改变。只要在源端算一个指纹，目的端再算一次，对比两个指纹是否一致即可知道是否改变。</p>
</li>
<li><p>应用四：远端Cache。某个CDN内容发布在网络环境中，针对一份源数据，在各地拥有多个二级Cache。这些Cache需要严格保证一致性，如果源发生了改变，指纹当然也改变了。那么可以随时拉取源端的指纹进行对比，发现不匹配则此Cache不再可用。</p>
</li>
<li><p>应用五：数字签名。将某人给出的一串特定字符转换成指纹。</p>
</li>
</ul>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-6f143cb79e866a4d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<h2 id="HASH冲突"><a href="#HASH冲突" class="headerlink" title="HASH冲突"></a>HASH冲突</h2><p>要完全杜绝Hash冲突的唯一办法就是当对比两个HASH值的之后发现二者匹配以后，可以再进行<strong>逐位对比</strong>，或者取相同的部分进行对比。</p>
<p>但是这样做的话会耗费大量的计算和IO资源，我们可以换一种思路，取<strong>两种HASH算法进行计算</strong>，如果两次都比对都相同，则可以认为是重复的。</p>
<h2 id="主机Dedup的过程"><a href="#主机Dedup的过程" class="headerlink" title="主机Dedup的过程"></a>主机Dedup的过程</h2><p>Dedup主要包含如下4个动作，注意这里面的Dedup软件是安装在主机上的。<br><img src="http://upload-images.jianshu.io/upload_images/1323506-b26816b8afd22491.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<ul>
<li><p>主机的Filter Driver实时监测写IO，透传到下层，同时复制一份到Dedup主模块。</p>
<p>  Dedup主模块将写IO Hash以后，存到指纹仓库里面，对Delay Block Bitmap置0。这个Bitmap是干嘛的？如果因为CPU负载过高等原因，Dedup引擎暂停工作，则这个写IO会被计算成Hash值存放，我们可以用一个bitmap来记录这写IO的位置，后续再进行计算。</p>
</li>
<li><p>Dedup主模块会在<strong>后台</strong>查找与指纹库里面重合的指纹，对于查找的菜块，会生成一个<strong>指针</strong>，并且保存在On Disk Pointer List中。这个动作是有Block Mapping Metadata Handler完成的，这个过程是真正的数据消重的过程。</p>
</li>
<li><p>针对Bitmap里面记录的暂未计算HASH的部分，还会在空闲的时刻完成后续的操作，并且把Bitmap的对应位置置回0</p>
</li>
</ul>
<p>这里面需要注意的是每个<strong>写IO</strong>都会写入存储介质中。那么大家肯定有疑问了，既然每个写IO都落到磁盘上，何来消重。</p>
<p>其实这个问题之前已经讨论了很多次了。谁来决定LUN的剩余空间，当然是上层文件。所以如果我们要想让主机端的Dedup有意义，只能</p>
<ul>
<li><p>让主机端文件系统感知到变化：这对块级Dedup来说是行不通的，因为块级Dedup的实现原理没有考虑到FS层的逻辑</p>
</li>
<li><p>模仿主机端对LUN的管理：可以在LUN上建立一层<strong>卷管理层</strong>，这样卷管理层会感知到哪些卷占用了多少物理空间。</p>
</li>
</ul>
<p>虽然运行在主机端、块级的Dedup，无法达到节省底层存储空间的目的。但是在<strong>备份</strong>的时候就非常有意义了，因为可以减少网络传输的量。</p>
<p>其实根本不用这么纠结，我们完全可以把块级Dedup安装在<strong>存储端</strong>，因为我们最终要节省的就是磁盘空间，而磁盘又是由存储设备管理的<br><img src="http://upload-images.jianshu.io/upload_images/1323506-2177aaa5e479ffec.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<h2 id="网络数据备份的Dedup"><a href="#网络数据备份的Dedup" class="headerlink" title="网络数据备份的Dedup"></a>网络数据备份的Dedup</h2><p>上面说过主机上的Dedup对备份是有意义的，我们可以传输更少的数据。不过这要求Dedup引擎与备份系统紧密配合，一般来说是作为备份软件的一个<strong>子模块</strong>。</p>
<p>这样做有个不好的地方，也就是会消耗主机的性能。我们也可以在主机后面进行Dedup，比如在介质服务器上，可以使用<strong>前台Dedup</strong>或者<strong>后台Dedup</strong></p>
<ul>
<li><p>如果备份介质是磁带，则必须以前台的方式来进行，因为磁带不可随机访问。</p>
<p>  前台Dedup可以采用<strong>局部和全局</strong>两种模式。区别在于对收到的数据是否还需要与<strong>之前备份过的数据</strong>进行对比。</p>
<ul>
<li><p>局部模式：Dedup引擎对收到的数据实时分割为Block然后计算HASH，并存放在指纹仓库里面。</p>
</li>
<li><p>全局模式：对接收来的数据计算HASH值以后，会将这个HASH值与之前曾备份过的数据的HASH值进行对比。</p>
<p>介质服务器都有本地硬盘，可以将要备份的数据流暂存在本次硬盘某处作为缓冲，然后由Dedup引擎在后台处理，最后写入磁带，这就是<code>D2D2T</code>。</p>
</li>
</ul>
</li>
<li><p>后台Dedup：如果备份介质是虚拟磁带库VTL，则可以使用这种方法。</p>
<p>  介质服务器首先将收的数据流直接写到磁盘中，当引擎触发之后，再从对应目标将数据读出并进行Dedup处理，最后写入介质空间，原有备份数据集删除。<br><img src="http://upload-images.jianshu.io/upload_images/1323506-f874996a7aa24c5c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
</li>
</ul>
<h2 id="Dedup思想的其他应用"><a href="#Dedup思想的其他应用" class="headerlink" title="Dedup思想的其他应用"></a>Dedup思想的其他应用</h2><p>增量备份、差量备份通常是在<strong>应用程序层</strong>来控制的，因为主要是由应用程序来负责记录备份的时间点以及文件的变化，此时备份软件主要是辅助作用。</p>
<p>然而备份软件自身如何实现LUN级别的增量和差量备份呢？</p>
<ul>
<li><p>差量备份：记录底层Block变化，将上一次备份之后，所发生的所有写对应的Block记录在bitmap中。这样就知道那些是需要再备份的。</p>
</li>
<li><p>增量备份：可以将上一层的Bitmap封存，新建一份空的Bitmap保存上一次<strong>差量或增量备份</strong>LUN的变化。当再次触发备份的时候，将Bitmap中置1的块备份下来，然后封存Bitmap，创建新的Bitmap。恢复的时候，可以根据需要恢复的<strong>备份点</strong>，将所有的Bitmap做一个OR操作，合成一份完整的Bitmap。然后将初次全备份的数据覆盖到目标上。这样就可以根据完整的Bitmap和每次增量备份的Block集提取对应的Block进行备份。</p>
</li>
</ul>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

        
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="en">
    <link itemprop="mainEntityOfPage" href="https://duyang2903.gitee.io/2019/11/15/%E5%A4%A7%E8%AF%9D%E5%AD%98%E5%82%A8%EF%BC%8C%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%8817%E7%AB%A0%EF%BC%89%EF%BC%8C%E6%95%B0%E6%8D%AE%E5%AE%B9%E7%81%BE/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="dy2903">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="dy2903的博客">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          
            <a href="/2019/11/15/%E5%A4%A7%E8%AF%9D%E5%AD%98%E5%82%A8%EF%BC%8C%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%8817%E7%AB%A0%EF%BC%89%EF%BC%8C%E6%95%B0%E6%8D%AE%E5%AE%B9%E7%81%BE/" class="post-title-link" itemprop="url">大话存储，学习笔记（17章），数据容灾</a>
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">Posted on</span>

              <time title="Created: 2019-11-15 10:48:24" itemprop="dateCreated datePublished" datetime="2019-11-15T10:48:24+08:00">2019-11-15</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">Edited on</span>
                <time title="Modified: 2019-11-13 21:27:14" itemprop="dateModified" datetime="2019-11-13T21:27:14+08:00">2019-11-13</time>
              </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <h1 id="数据容灾"><a href="#数据容灾" class="headerlink" title="数据容灾"></a>数据容灾</h1><blockquote>
<p>数据备份系统只能保证实际上被安全复制了一份，如果生产系统故障，必须将备份数据尽快的恢复到生产系统中继续生产，就叫<code>容灾</code>。</p>
</blockquote>
<p>容灾可以分为四个级别：</p>
<ul>
<li><p>数据级容灾：只是将生产站点的数据同步到远端。</p>
</li>
<li><p>与应用结合的数据级容灾：保证对应应用数据一致性。</p>
</li>
<li><p>应用级容灾：需要保证灾难发生以后，需要保证原生成系统中的应用系统在灾备站点可用。</p>
</li>
<li><p>业务级容灾：除了保证数据、应用系统在灾备站点可用，还要保证整个企业的业务系统仍对外可用，是最终层次的容灾。</p>
</li>
</ul>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-9fad26a018cc9b07.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<h2 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h2><p>如果要充分保证数据的安全，只是在本地做备份是不够的，所以需要在远程建另一个系统，并包含当前生产系统的全部数据，这个系统须</p>
<ul>
<li><p>要保证主生产系统的数据<strong>实时</strong>的传输到远程备份系统上。</p>
</li>
<li><p>主故障后，必须将应用程序切换到远程备份系统上。</p>
</li>
</ul>
<p>那么备份和容灾有什么区别呢？生产系统就好比手机，备份就是把手机上的数据备份到电脑上，但是如果这个手机坏了呢？要恢复数据需要大量的时间。</p>
<p>那么<code>容灾</code>就是我们有两部手机，而且他们的数据是使用云实时同步的，所以可以<strong>无缝切换</strong>。</p>
<p>如果我们预算充足，可以使用一直两台手机，那还需要<strong>备份</strong>吗？当然需要，比如某个时刻，我们把手机里面的某个联系人给误删了，因为容灾的手机是实时同步的，很难说能通过另一部手机找回来。但是如果之前有备份过数据，完全可以通过之前的备份进行恢复。</p>
<p>下面继续谈<code>容灾</code>。对于一个企业IT生产系统，主要有4个组件：</p>
<ul>
<li><p>生产资料：原始数据</p>
</li>
<li><p>生产工具：服务器等基础架构</p>
</li>
<li><p>生产者：业务应用程序</p>
</li>
<li><p>产品：对外提供的服务信息</p>
</li>
</ul>
<p>下面将对这四大组件的容灾进行讲解</p>
<h2 id="生产资料容灾"><a href="#生产资料容灾" class="headerlink" title="生产资料容灾"></a>生产资料容灾</h2><p>生产资源容灾指的就是对原始数据进行容灾。<strong>这最重要的，因为没有生产资料一切等于从头再来。</strong><br>要设计这样一套生产资料容灾，需要注意的是</p>
<ul>
<li><p>要把变化的<strong>实时</strong>同步到备用系统，方法是</p>
<ul>
<li><p>将某时刻的数据传送到备用系统</p>
</li>
<li><p>将此时候后变化数据同步到备用系统</p>
</li>
<li><p>这样就做了一次同步了，之后只需要在数据变化以后才把变化的数据传送到备用系统。</p>
</li>
</ul>
</li>
<li><p>数据必须至少保留额外一份。在容灾的同时还需要数据备份（避免误删等逻辑错误）</p>
</li>
</ul>
<p>如下为相应的拓扑：</p>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-e776d0382b63f776.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<p>主备站点都有相同的生产工具，使用网络相连。可以通过两种方式来进行同步：</p>
<ul>
<li><p>通过前端网络进行同步</p>
</li>
<li><p>通过后端SAN网络进行同步。</p>
</li>
</ul>
<h3 id="通过前端网络同步"><a href="#通过前端网络同步" class="headerlink" title="通过前端网络同步"></a>通过前端网络同步</h3><p><img src="http://upload-images.jianshu.io/upload_images/1323506-aee32657c991beaf.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<ul>
<li><p>通过路由器连接到专线或者Internet</p>
</li>
<li><p>变化的数据通过路由器传送到备站点的路由器上。</p>
</li>
<li><p>通过交换机传到备服务器上，写入磁盘阵列</p>
</li>
</ul>
<p>那么到底选择专线还是Internet呢？专线可以保证数据同步的实时性，但是不适合大数量的传输。如果实时性要求不高，而且数据量大的时候，可以将主备站点接入100Mbps的Internet。</p>
<p>可以看出这种方式经过了前端网络，所以必须在每台需要<strong>备份的服务器上安装软件</strong>进行同步，这种软件可以监视目录中的数据变化，然后与远端的软件进行通信，写入相同的文件目录中。</p>
<p>这种方式的同步一般都是<strong>文件级</strong>的同步，对底层卷的数据块变化不做同步。</p>
<h3 id="案例：DB2数据的HADR组件容灾"><a href="#案例：DB2数据的HADR组件容灾" class="headerlink" title="案例：DB2数据的HADR组件容灾"></a>案例：DB2数据的HADR组件容灾</h3><p>DB2数据库利用主备上的数据库软件模块（HADR）来实现两端的数据同步。而且同步的是不卷上的原始数据，而是对数据操作的描述，也就是<strong>日志</strong>。这样的好处是，不需要传输数据，备份机收到日志以后，在备机的磁盘上重做操作即可。</p>
<p><code>HADR:High Availability Disaster Recovery</code>，是数据库级别的高可用性数据复制机制。需要两台数据库服务器：primary , standby</p>
<ul>
<li><p>当<code>主数据库</code>发生事务性操作，将<strong>日志</strong>通过TCP/IP传送到<code>备数据库</code>，然后备机对日志文件进行重放<strong>Replay</strong>，从而保持数据的一致性。</p>
</li>
<li><p>当<code>主数据库</code>故障，备机可以接管主数据库，而客户端应用程序的数据库连接可以通过自动客户端<strong>重新路由</strong>（Automatic Client Reroute）转移到新的主服务器。</p>
</li>
<li><p>当原来的主数据库服务器修复了，作为新的备用数据库加入HADR。</p>
</li>
</ul>
<blockquote>
<p>需要注意的是处于<strong>备用</strong>角色的数据库不能被访问。</p>
</blockquote>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-7f11071195f8c22d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<h3 id="通过后端网络实现同步"><a href="#通过后端网络实现同步" class="headerlink" title="通过后端网络实现同步"></a>通过后端网络实现同步</h3><p>通过后端网络进行同步，数据不会流经前端网络，而全部通过后端网络传输到备份的存储上。所以需要将主站点和备站点的后端网络设施连接起来。要么直接拉光纤，要么用专线。</p>
<p>如果用专线的话，需要增加额外的协议转换设备，现在电信部门的光纤专线一般为SDH传输方式，接入到用户端的时候，一般将信号调制成E1、OC3等编码方式。</p>
<p> <img src="http://upload-images.jianshu.io/upload_images/1323506-c8458c7528c7e304.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<p>上图中，FC协议，经过FCIP网关，变成基于以太网的IP协议，（FC over IP over ETH）。经过E1/以太网转换器，承载到了E1协议上，然后多路E1信号汇聚到光端机，通过一条或者多条光纤，传输给电信部门的SDH交换设施进行传输。</p>
<p>这样我们就将主站点和备站点的后端网络打通了，此时主服务器就可以访问到备份的磁盘阵列，也就是说主站点的服务器可以同时操作<strong>本地磁盘和备站点的磁盘阵列</strong>了。</p>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-bdeed0fdc6bacccd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<p>我们来看一下这种方式的路径：</p>
<blockquote>
<p>本地磁盘+SAN交换——本地服务器内存——SAN网络交换——电信部门网络——远端SAN网络交换——远端磁盘阵列</p>
</blockquote>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-2c9f459895f21276.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<p>数据到了远端SAN不需要再经过服务器，<strong>因为有了对方存储设备的直接访问权。</strong>但是整个过程中，仍然至少需要一台<strong>服务器</strong>，服务器上需要安装一个软件，可以将数据从本地卷A提取出来，然后直接通过SAN网络写到位于备份站点的卷B上。</p>
<p>但是试想一下，如果数据直接在内存中生成的，那么同时在A和B上各写一份，速度岂不是更快，这种方式又叫“<code>卷镜像</code>”，因为可以时时刻刻保持两个卷完全相同，它能保证数据同步的实时性，<strong>但是不适合大规模远距离的数据同步</strong>。</p>
<p>同时还需要注意的是，卷镜像的的同步软件工作在卷这一层，可以感知数据块的变化，而不是文件的变化。缺点在于对网络速度要求更高，所以成本也更高。</p>
<h3 id="通过数据存储设备实现同步"><a href="#通过数据存储设备实现同步" class="headerlink" title="通过数据存储设备实现同步"></a>通过数据存储设备实现同步</h3><p>之前讲的通过前端网络和通过后端网络的方式，都使用了一个<code>泵</code>来提供动力。而如果将数据同步软件安装在存储设备上，岂不是更省事。而且这样彻底解放了服务器，所有工作都由磁盘阵列完成。</p>
<p>这种方式的同步，不会识别卷上的文件系统，所以同步的是块。<strong>而且要求主和备的存储设备型号一致。</strong>因为不同厂家的产品无法实现直接同步。<br><img src="http://upload-images.jianshu.io/upload_images/1323506-6a3e8eb87f7a3501.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<p>这种方法的缺点是不能保证数据对<strong>应用程序</strong>的可用性。</p>
<p>因为存储设备与应用程序之间还有操作系统这一层，操作系统也有自己的缓存机制，所有有可能造成数据的不一致性。</p>
<p>总结：</p>
<ul>
<li><p>使用前端网络进行同步，路径最长，但是成本也最低。</p>
</li>
<li><p>使用后端网络进行同步，实时性强，但是对后端链路要求也高。不适合于数据量多的时候。</p>
</li>
<li><p>使用存储设备直接进行同步，路径最短，不占用服务器。但是仍然不适合于远距离低速链路环境。而且还不能数据对应用程序的可用性。</p>
</li>
</ul>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-6c6484d396b37b94.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<h2 id="容灾中数据的同步复制和异步复制"><a href="#容灾中数据的同步复制和异步复制" class="headerlink" title="容灾中数据的同步复制和异步复制"></a>容灾中数据的同步复制和异步复制</h2><h3 id="同步复制"><a href="#同步复制" class="headerlink" title="同步复制"></a>同步复制</h3><p>下图是基于存储设备的自主同步环境。</p>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-d641ede60d0c59d9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<ul>
<li><p>主向磁盘发出IO请求，向某LBA写入数据，待写数据入缓存，<strong>此时控制器不会给主的HBA驱动程序发送成功</strong></p>
</li>
<li><p>主磁盘阵列将变化的数据从缓存中写入LUN A，<strong>此时主的数据同步引擎感知</strong>，将变化的数据块从缓存中通过SAN交换机发送到备的缓存中。</p>
</li>
<li><p>备磁盘阵列运行的同步引擎接收到数据后，在FC协议隐式的发一个<strong>ACK</strong>或者通过上层显试的发给主站点</p>
</li>
<li><p>主收到应答，向服务器发一个FC协议的隐式<strong>ACK</strong>。服务器上的FC HBA驱动程序探测成功。</p>
<p>  若备站点迟迟未收到数据，则不会返回成功，应用程序会等待。如果此时应用程序使用的是<strong>同步IO</strong>，则相关进程会挂起，称为<code>IO等待。</code></p>
<p>  <strong>所以同步复制的特点是主站点必须等待备份站点的成功信号，保持严格的同步，一荣俱荣，一损俱损。</strong></p>
</li>
</ul>
<h3 id="异步复制"><a href="#异步复制" class="headerlink" title="异步复制"></a>异步复制</h3><p>相对于同步复制，两边的步调不需要一致，要保证重要的事情先做完，所以会存在一定的数据不一致。</p>
<ul>
<li><p>主向磁盘发出IO请求，待写数据进入<strong>控制器缓存</strong>，如果此时</p>
<ul>
<li><p>主控制器设置为Write Back模式：则立刻返回应答。</p>
</li>
<li><p>主控制器设置为Write Through模式，则先写入LUN A以后，再返回ACK。</p>
</li>
</ul>
</li>
<li><p>主站点将数据通过SAN网络发送到备站点的缓存。</p>
</li>
<li><p>备站点磁盘成功接收，则返回成功。</p>
</li>
</ul>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-f1ccd5b392cff340.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-a21c1d7b2e3e807e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<h2 id="生产者容灾——应用程序容灾"><a href="#生产者容灾——应用程序容灾" class="headerlink" title="生产者容灾——应用程序容灾"></a>生产者容灾——应用程序容灾</h2><p>之前讲的都是生产资料的容灾，也就是整个系统最重要的数据的容灾。而对于生产者，无疑就是服务器上的应用程序，如果主发生故障，需要<strong>在备站点重新运行这些应用程序</strong>。最直观的想法是，在备站点预备应用程序的安装文件，一定主出现故障，在备上配置这些应用程序，但是实际上应用程序安装和配置需要大量的时间。所以<strong>可以将备份站点预装应用程序，但是不工作，这样就可保证同一时刻整个IT系统只有一个站点的生产者处理一份数据</strong></p>
<p>既要求处理同一份数据，又要求发生事故的时候，备份站点的生产者立即启动，要做到这点，需要让备份站点的应用程序感知到主站点的应用程序状态，一旦发现故障，立即启动开始生产。</p>
<p>在之前的章节中，我们说到了<strong>高可用群集</strong>，在容灾系统领域，群集的范围扩大到了异地，主备可能相隔很远，交换运行状态的数据量很小，最好使用专线，这样可以很好的保证QoS。</p>
<p>传统的HA软件是使用<strong>共享存储</strong>的方式来作用的，即在HA系统中，共享一份物理存储，不管谁来操作这份数据，最终只有一份，而且是一致，有上下文逻辑关系的。</p>
<p>所以HA软件是基于资源切换的，把组件看作是资源，比如应用、IP地址、存储卷等。<br>当故障时，</p>
<ul>
<li><p><strong>备份机</strong>HA软件会检测到对方的故障，</p>
</li>
<li><p>然后强行将资源迁移到本地，比如在备份机上修改网卡的IP地址，并发出ARP广播来刷新所有广播域的客户端以及网关的ARP记录</p>
</li>
<li><p>挂载共享存储设备上的卷，</p>
</li>
<li><p>最后启动备份应用系统。</p>
</li>
</ul>
<p>这样应用系统可以访问共享卷，客户端也可以使用原来的IP地址来访问服务器，这样生产就可以继续下去。</p>
<p>但是在异地容灾系统中，主备站点各有一份数据，所以必须保证数据的同步。这也是为什么<strong>两个站点同时只有一个在工作</strong>，这样的话才能以一边数据为准，另一边与之同步。</p>
<h3 id="本地容灾"><a href="#本地容灾" class="headerlink" title="本地容灾"></a>本地容灾</h3><p>本地HA系统中，多个节点如果共同拥有同一个卷，但是同一时刻只有一个节点能挂载它，这种模式叫<strong>共享存储模式</strong></p>
<p>与之对应的是<strong>Share-Nothing模式</strong>，每个节点都有自己独占的存储卷，怎么进行数据共享呢？可以通过<strong>同步复制技术</strong>同步到所有节点上。若某节点发生故障，这个节点对应的备份节点启动应用程序。因为之前的数据已经同步过了，所以数据一定是一致的。</p>
<p>在Share-Nothing模式下，不存在任何的接管问题，所以客户端需要感知服务端群集这种切换动作，通过客户端进行<strong>配置的切换</strong>即可。</p>
<p>可以对共享存储和Share-Nothing两种存储模式进行对比。</p>
<table>
<thead>
<tr>
<th></th>
<th>共享存储</th>
<th>Share-Nothing</th>
</tr>
</thead>
<tbody><tr>
<td>数据本身是否容灾</td>
<td>×</td>
<td>√</td>
</tr>
<tr>
<td>软硬件成本</td>
<td>高</td>
<td>低</td>
</tr>
<tr>
<td>前端网络资源消耗</td>
<td>低</td>
<td>高</td>
</tr>
<tr>
<td>管理难度</td>
<td>高</td>
<td>低</td>
</tr>
<tr>
<td>维护数据是否需要停机</td>
<td>√</td>
<td>×</td>
</tr>
<tr>
<td>实现的复杂度</td>
<td>高</td>
<td>低</td>
</tr>
<tr>
<td>是否需要第三方软件</td>
<td>√</td>
<td>×</td>
</tr>
<tr>
<td>故障因素数量</td>
<td>3个</td>
<td>2个</td>
</tr>
</tbody></table>
<ul>
<li><p>数据本身是否容灾</p>
<ul>
<li><p>共享存储：数据损坏，必须使用镜像进行还原。而且要停机。</p>
</li>
<li><p>Share-Nothing：每个节点都有自己的数据拷贝，若损坏，可切换到另外的节点，不影响应用，不停机。修复后的节点可以重新加入容灾系统。</p>
</li>
</ul>
</li>
<li><p>软硬成本</p>
<ul>
<li><p>共享：需要外接磁盘阵列，为了保证数据访问速度，必须自身实现RAID，主机也需要安装适配器。成本高。需要HA软件</p>
</li>
<li><p>Share-Nothing:各个节点各自保存数据，不需要外接存储系统，不需要额外的HA软件</p>
</li>
</ul>
</li>
<li><p>前端网络耗费</p>
<ul>
<li><p>共享存储：前端只需要交互控制信息，资源耗费较小。</p>
</li>
<li><p>Share-Nothing:数据同步靠前端，对资源消耗很大。</p>
</li>
</ul>
</li>
<li><p>管理难度：</p>
<ul>
<li><p>共享：需要管理节点间的交互配置，还需要管理外部存储，增加了管理难度</p>
</li>
<li><p>Share-Nothing:只需要管理节点配置。</p>
</li>
</ul>
</li>
<li><p>是否停机</p>
<ul>
<li><p>共享：需要将数据从单机转移到共享存储供其他节点使用，需要停机来保证一致性。</p>
</li>
<li><p>Share-Nothing：数据同步是动态的，不需要停机。</p>
</li>
</ul>
</li>
<li><p>实现复杂度</p>
<ul>
<li><p>共享存储：有三种基本元素：节点、节点间的交互、共享数据。如果使用共享存储模式做容灾，需要将数据移动到共享存储上，增加额外的工作量和不可控因素</p>
</li>
<li><p>Share-Nothing：只有两种元素 节点&amp;节点交互</p>
</li>
</ul>
</li>
<li><p>第三方</p>
<ul>
<li><p>共享存储：备份节点需要通过HA软件来监控主节点的状态，发生故障的时候自动接管，如MSCS</p>
</li>
<li><p>share-Nothing：不需要第三方软件参与</p>
</li>
</ul>
</li>
<li><p>故障因素</p>
<ul>
<li><p>共享存储：OS、应用程序、HA软件</p>
</li>
<li><p>Share-nothing：OS、应用程序</p>
</li>
</ul>
</li>
</ul>
<h3 id="异地容灾"><a href="#异地容灾" class="headerlink" title="异地容灾"></a>异地容灾</h3><p>如果主站点和备站点不在同一个机房中，这样备份应用程序需要跨越很远的距离来与主程序交互状态。只是说这种交互包很小，不需要担心延时的问题。</p>
<h4 id="IP切换"><a href="#IP切换" class="headerlink" title="IP切换"></a>IP切换</h4><p>在<strong>异地容灾系统</strong>，主服务器和备服务器<strong>不大可能在同一个广播域</strong>，所以需要通过网关来转发IP包，正因为此不能用<strong>资源切换</strong>的方式来切换IP地址。</p>
<p>如果想故障后，客户端继续使用原来的IP地址连接<strong>备份服务器</strong>，那么可以在<strong>路由</strong>上做文章。动态修改路由器上的路由表，将IP包路由到备份站点而不是主站点。如果利用域名来访问服务器，那么可以直接在DNS设备上修改IP指向记录来实现。</p>
<h4 id="卷切换"><a href="#卷切换" class="headerlink" title="卷切换"></a>卷切换</h4><p>异地容灾系统在主站点和备站点各有卷，两个卷通过前端或者后端网络进行同步。</p>
<p>如果备的HA软件检测到主站点通信失败，通过某种方式，断开<strong>同步</strong>关系（若不断开，卷会被锁定而不可访问）。然后就是重新挂载备站点的卷</p>
<p>此时同步引擎可以是运行在存储设备上，也可以由HA来执行。</p>
<ul>
<li><p>如果同步引擎是运行<strong>在存储设备</strong>上的，必须由管理员手动利用存储设备的配置工具来断开同步关系。断开了以后，本地的卷才可以被访问，然后HA软件可以在备份机上调用操作系统相关功能来挂载这个卷。</p>
</li>
<li><p>如果同步引擎本来就是<strong>HA来执行</strong>的，那么HA软件可以自动断开同步关系，在备份机上挂载对应的卷。</p>
</li>
</ul>
<h4 id="异地容灾的应用切换"><a href="#异地容灾的应用切换" class="headerlink" title="异地容灾的应用切换"></a>异地容灾的应用切换</h4><p>应用，也就是生产者的切换，是所有HA容灾系统在故障发生后所执行的最后一步。与共享存储式的HA容灾一样，异地容灾的应用切换，是有备机的HA软件来执行<strong>脚本</strong>，或者调用相应的<strong>接口</strong>来启动备份机的应用的。</p>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-1e242fcd9f8abb1f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

        
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="en">
    <link itemprop="mainEntityOfPage" href="https://duyang2903.gitee.io/2019/11/15/%E5%A4%A7%E8%AF%9D%E5%AD%98%E5%82%A8%EF%BC%8C%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%886%E7%AB%A0%EF%BC%89%EF%BC%8C-%E7%A3%81%E7%9B%98%E9%98%B5%E5%88%97/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="dy2903">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="dy2903的博客">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          
            <a href="/2019/11/15/%E5%A4%A7%E8%AF%9D%E5%AD%98%E5%82%A8%EF%BC%8C%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%886%E7%AB%A0%EF%BC%89%EF%BC%8C-%E7%A3%81%E7%9B%98%E9%98%B5%E5%88%97/" class="post-title-link" itemprop="url">大话存储，学习笔记（6章），-磁盘阵列</a>
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">Posted on</span>

              <time title="Created: 2019-11-15 10:48:24" itemprop="dateCreated datePublished" datetime="2019-11-15T10:48:24+08:00">2019-11-15</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">Edited on</span>
                <time title="Modified: 2019-11-13 21:27:13" itemprop="dateModified" datetime="2019-11-13T21:27:13+08:00">2019-11-13</time>
              </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <h1 id="磁盘阵列"><a href="#磁盘阵列" class="headerlink" title="磁盘阵列"></a>磁盘阵列</h1><h2 id="JBOD"><a href="#JBOD" class="headerlink" title="JBOD"></a>JBOD</h2><p>在过去一台服务器只能放两三块盘，远远不能满足要求，所以可以把盘放到主机的外面。也就是说专门拿一个箱子，所有磁盘都放在机箱里面，而且独立电源和散热，接口方面，内部其实就是一条SCSI线缆，这就形成了<strong>磁盘柜(Just a Bound Of Disk ， JBOD)</strong>，顾名思义，实际上就是“一串磁盘”</p>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-bcbb850708639578.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<h2 id="独立的外部磁盘阵列"><a href="#独立的外部磁盘阵列" class="headerlink" title="独立的外部磁盘阵列"></a>独立的外部磁盘阵列</h2><p>JBOD的内部不含RAID卡，这样，如果要调整RAID的话，还需要重启主机，影响主机里面的应用。那么最好是可以把RAID功能做到磁盘箱内部。</p>
<p>如下图所示，凡是<strong>自带RAID控制器的</strong>盘柜就叫<strong>磁盘阵列</strong>。通过外部的SCSI接口，连接到主机上端的SCSI端口。</p>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-c6708875ee5d74ed.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<p>主机的SCSI控制器与盘阵SCSI控制器相比，盘阵的SCSI控制器作为Target模式，被主机SCSI控制器操控。</p>
<p>而在右边的SCSI总线上，盘阵的S2控制器作为Initiator模式，占据主动权。磁盘均为SCSI Target，受控于Initiator</p>
<h3 id="前端和后端"><a href="#前端和后端" class="headerlink" title="前端和后端"></a>前端和后端</h3><p>对盘阵来说，左边为前端，面向主机提供对外服务<br>面向自己管理的磁盘就变成了后端。也就是右边的部分。</p>
<h3 id="内部接口和外部接口"><a href="#内部接口和外部接口" class="headerlink" title="内部接口和外部接口"></a>内部接口和外部接口</h3><ul>
<li>内部接口：盘阵RAID控制器连接内部磁盘时用的接口：可以连接IDE磁盘等</li>
<li>外部接口：盘阵控制器对于主机端，提供什么接口，</li>
</ul>
<p>内外接口可以不一样，比如内部连接IDE磁盘，外部用SCSI接口连接主机。（仅限于盘阵，盘柜必须一样）</p>
<p>因为盘阵控制器是一个虚拟化引擎，可以不一致，即使内部是IDE的，也可以向主机报告有多少LUN</p>
<h3 id="多外部接口"><a href="#多外部接口" class="headerlink" title="多外部接口"></a>多外部接口</h3><p>有多个接口是为了连接多台的主机。</p>
<p>每个由盘阵RAID控制器生成的逻辑磁盘，<strong>可以通过设置只分配到其中一个口，连接到其他口的主机就不会看到这个LUN。</strong></p>
<p>也可以把一个LUN同时分配到两个口，两台主机对一个LUN写数据，容易造成数据不一致。</p>
<h3 id="关于LUN"><a href="#关于LUN" class="headerlink" title="关于LUN"></a>关于LUN</h3><p>LUN是SCSI ID的更细一级的地址号。每个SCSI ID下面可有更多的LUN ID 。</p>
<p>大型磁盘阵列有几千个虚拟磁盘，但是每条SCSI总线最多允许16个设备，所以为每个虚拟磁盘分配一个SCSI ID不够用。</p>
<p>可以在一个SCSI ID虚拟多个LUN地址，每个LUN地址对应一个虚拟磁盘。</p>
<blockquote>
<p><code>LUN</code>：硬件层次生成的虚拟磁盘统称为LUN。<br><code>卷</code>：软件生成的虚拟磁盘</p>
</blockquote>
<h2 id="双控制器磁盘阵列"><a href="#双控制器磁盘阵列" class="headerlink" title="双控制器磁盘阵列"></a>双控制器磁盘阵列</h2><p>如果控制器只有一个，则会存在单点故障，所以至少有两个控制器。双控制器需要相互通信，一般使用PCI总线进行互联。</p>
<p>而两个控制器的协同方式有两种，Active-Standby 、Dual-Active</p>
<h3 id="Active-Standby（HA）"><a href="#Active-Standby（HA）" class="headerlink" title="Active-Standby（HA）"></a>Active-Standby（HA）</h3><blockquote>
<p>HA方式：两个控制器同一时刻只有一个在工作，另一个在等待、同步和监控状态，只是在故障以后才接管。</p>
</blockquote>
<p>两控制器各占一个ID 。剩余14个ID给磁盘，</p>
<p>为了预防<code>脑分裂</code>，备份控制器在接管之前需要将<strong>主控断电或者重启</strong>，释放其总线使用权，然后接管前端和后端总线。</p>
<blockquote>
<p>主机端必须使用两个SCSI适配器分别连接到盘阵上的控制器，但是这样做，主机端必须通过某种方式感知到HA策略，并在故障发生时切换。</p>
</blockquote>
<p>对于FC盘阵来说，使用<strong>双控</strong>及主机端使用<strong>双FC适配卡</strong>非常普遍。</p>
<h3 id="Dual-Active"><a href="#Dual-Active" class="headerlink" title="Dual-Active"></a>Dual-Active</h3><blockquote>
<p>所谓Dual-active，也叫控制器双活，指的是两个控制器<strong>同时工作，对所有后端总线有通路，但是每个总线平时只被一个控制器管理，另一个不触动</strong>。<br>可以将后端一半数量的总线交由一个控制器管理，另一半交由另一个控制器管理。一旦损坏，可以立刻接管所有的总线，比Active-Standby更高效。</p>
</blockquote>
<h3 id="脑分裂Split-Brain"><a href="#脑分裂Split-Brain" class="headerlink" title="脑分裂Split Brain"></a>脑分裂Split Brain</h3><p><strong>脑裂</strong>指的是控制器之间的<strong>通路</strong>出现了问题。也就是说两个控制器其实是正常的，但是检测不到对方的 存在。所以都会尝试接管所有的总线。类似于精神分裂。</p>
<p>解决方案：<br>加入一个<code>仲裁者</code></p>
<ul>
<li>使用两个控制器都能写到的硬盘，向其写入自己的仲裁信息，如果脑分裂，就看谁在上面最后写了信息。</li>
<li>电源控制器：向电源控制器发送信号，让对方重启并进入Standby</li>
</ul>
<p>接管了总线的控制器一般会对总线上所有的磁盘进行SCSI Reserve操作，即预订操作。</p>
<p>总线上所有目标设备一旦被预订，便不再接受其他控制器的IO请求。</p>
<h2 id="连接多个扩展柜"><a href="#连接多个扩展柜" class="headerlink" title="连接多个扩展柜"></a>连接多个扩展柜</h2><p>到现在，一个盘柜里面有两个磁盘控制器、有磁盘，但是一条SCSI总线最多15块磁盘，为了15块磁盘，使用两个RAID控制器有点不值。</p>
<p>下图为一个机头，它带有一个扩展磁盘接口以及两个控制器。</p>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-128ed7fa1ba8cefe.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<p>然后使用这个机头连接JBOD扩展柜</p>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-cd6739cd9108e529.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"><br>总结一下：</p>
<blockquote>
<p><strong>机头</strong>：带有控制器的磁盘柜，就像是火车的机头一样，是提供动力的，机头也可以有磁盘。<br><strong>扩展柜</strong>：用于扩展容量的JBOD，就如同车厢，没有动力，但是需要有基本的供电和冷却系统。</p>
</blockquote>
<h2 id="主机和磁盘阵列本是一家"><a href="#主机和磁盘阵列本是一家" class="headerlink" title="主机和磁盘阵列本是一家"></a>主机和磁盘阵列本是一家</h2><h3 id="盘阵控制器的主机化"><a href="#盘阵控制器的主机化" class="headerlink" title="盘阵控制器的主机化"></a>盘阵控制器的主机化</h3><p>可以说<strong>盘阵控制器</strong>本来但是一个简单的主机系统</p>
<p>所以完全可以用一台<strong>服务器</strong>来充当存储系统的控制器。</p>
<p>插入几张SCSI卡作为前端接口卡，若干SCSI卡作为后端连接磁盘箱的接口卡,然后设计软件从/向后端读写数据，经过处理或者虚拟化后，传送给前端的主机服务器。</p>
<p>目前有两种趋势：</p>
<ul>
<li>主机充当控制器</li>
<li>高集成度的芯片作为控制器的核心</li>
</ul>
<h3 id="盘阵类型"><a href="#盘阵类型" class="headerlink" title="盘阵类型"></a>盘阵类型</h3><p>按照前端-后端接口分，有</p>
<ul>
<li>SCSI-FC盘阵：前端是FC接口的盘阵，后端是SCSI磁盘</li>
<li>FC-FC盘阵</li>
<li>SATA-FC盘阵</li>
<li>SCSI-SCSI盘阵</li>
</ul>
<p>后面会讲到FC-FC盘阵，这是目前高端盘阵所采用的架构。</p>
<h2 id="SAN（Storage-area-network）"><a href="#SAN（Storage-area-network）" class="headerlink" title="SAN（Storage area network）"></a>SAN（Storage area network）</h2><p>RAID 控制器相当与路由器，也就是协议转换器。</p>
<blockquote>
<p><code>SAN，存储区域网</code>： 将磁盘放到主机外部，存储设备和主机之间形成了一个独立的网络</p>
</blockquote>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-b8ef4f1af760ab7d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

        
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="en">
    <link itemprop="mainEntityOfPage" href="https://duyang2903.gitee.io/2019/11/15/%E5%A4%A7%E8%AF%9D%E5%AD%98%E5%82%A8%EF%BC%8C%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%8815%E7%AB%A0%EF%BC%89%EF%BC%8CNoSQL/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="dy2903">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="dy2903的博客">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          
            <a href="/2019/11/15/%E5%A4%A7%E8%AF%9D%E5%AD%98%E5%82%A8%EF%BC%8C%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%8815%E7%AB%A0%EF%BC%89%EF%BC%8CNoSQL/" class="post-title-link" itemprop="url">大话存储，学习笔记（15章），NoSQL</a>
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">Posted on</span>

              <time title="Created: 2019-11-15 10:48:24" itemprop="dateCreated datePublished" datetime="2019-11-15T10:48:24+08:00">2019-11-15</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">Edited on</span>
                <time title="Modified: 2019-11-13 21:27:14" itemprop="dateModified" datetime="2019-11-13T21:27:14+08:00">2019-11-13</time>
              </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>互联网运营商（NSP）的数据中心是数据最集中的地方，也正是因为海量的数据存储与访问，传统的存储架构已经无法满足了现有的需求。</p>
<p>比如每秒几十万次的随机IOPS、每秒10GB的流量，一般都需要使用高端存储，当然价格将不便宜。而且扩展性不好，扩容成本高。</p>
<p>业务的不断增加，导致互联网运营商逐步使用分布式系统来构建底层文件系统及数据库，比如Google的GFS+Bigtable</p>
<p>我们先来看一下为了应对大并发、大流量下，架构的逐步的变化，最后引入NoSQL。</p>
<h1 id="传统数据库架构的演进"><a href="#传统数据库架构的演进" class="headerlink" title="传统数据库架构的演进"></a>传统数据库架构的演进</h1><h2 id="使用缓存技术"><a href="#使用缓存技术" class="headerlink" title="使用缓存技术"></a>使用缓存技术</h2><p>随着访问量的上升，流量的增加，使用MySQL的架构的网站在数据库上出现了性能问题。</p>
<p>要应对传统的MySQL性能不足的问题，最容易想到的就是加<strong>缓存</strong>。如果只是使用文件缓存，由于多台Web服务器通过文件缓存不能共享，所以性能并没有那么显著的提升。</p>
<p>那么，我们能不能把缓存单独抽取出来，形成一个<strong>缓存服务器</strong>，使用这台服务器的大内存来进行缓存，而且这个缓存服务器还可以分布式部署，既保证了共享，又保证了性能。</p>
<p>最典型的代表就是Memcached缓存服务器，我们可以使用一致性Hash算法来进行多台服务器的扩展。<br>详细可见另一篇文章<a href="http://www.cnblogs.com/dy2903/p/8324415.html" target="_blank" rel="noopener">Memcached集群​</a></p>
<h2 id="MySQL的主从读写分离"><a href="#MySQL的主从读写分离" class="headerlink" title="MySQL的主从读写分离"></a>MySQL的主从读写分离</h2><p>使用缓存服务器只能算是权宜之计，访问量继续上涨的话，数据库还是会有瓶颈。因为互联网应用主要还在于<strong>读</strong>，既然读压力这么大，我们能不能使用集群来负载分担呢。</p>
<p>但是数据库因为需要保证它的原子性、一致性等，不能简单的使用多台服务器并发访问这种架构。</p>
<p>我们可以进行读写分离，将数据库分为Master和Slave两种角色，Master主要用于写，Slave主要用于读，而且Slave可以多台来负载均衡。</p>
<p>这样就可以提高读写性能和读库的可扩展性。具体可以参考<a href="https://www.jianshu.com/p/1b82a1f6a586" target="_blank" rel="noopener">数据库（七），读写分离到CQRS</a>。</p>
<h2 id="分表分库"><a href="#分表分库" class="headerlink" title="分表分库"></a>分表分库</h2><p>使用 Memcached高速缓存和MySQL主从复制，可以缓解<strong>读压力</strong>，但是写压力怎么办？</p>
<p>最开始MySQL使用MyISAM引擎，它是使用<strong>表锁的</strong>，高并发有严重的锁问题。于是MySQL使用InnoDB引擎代替它。</p>
<p>同时我们还可以进行分表分库来缓解写压力：</p>
<p>有两种方式：</p>
<ul>
<li><p>水平切：一张表，水平切分为多张表，每个节点存储一张子表，同时保留有另外两个副本。所以每张子表都包含原表所有的列。</p>
</li>
<li><p>垂直切分：也就是把一张表竖直的切分，原来的列拆分开，相当于把数据打散，可以获得超高的随机查询性能。</p>
</li>
</ul>
<p>水平切分不需要人参与，盲切分即可。<br>而垂直切分相当于基于业务层面的切分，具有一定的人为介入度。</p>
<h2 id="MySQL的问题"><a href="#MySQL的问题" class="headerlink" title="MySQL的问题"></a>MySQL的问题</h2><p>上面讲到了MySQL在应对大流量大并发的情况下做的努力，底层架构可谓是越来越复杂，<strong>相应的，上层的应用也会越来越复杂</strong>。虽然有些公司开发了<strong>中间件层</strong>来屏蔽开发的复杂性，但是避免不了架构的复杂。</p>
<p>那么之前的方法主要的缺点在于：</p>
<ul>
<li>不够灵活：表结构更改困难，关系型数据库的表结构在一开始的时候就确定好了，很难更改。</li>
</ul>
<ul>
<li>扩展性的问题还是没有解决，MySQL推出的集群解决方案，只能保证可靠性，无法保证性能。</li>
</ul>
<ul>
<li>MySQL经常需要存放大文本字段，导致数据库恢复的时候特别慢。</li>
</ul>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-e68c0a9b9097c9a6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<p>所以关系型数据库很强大，但是不代表它能应付所有的应用环境，如果我们想要保证良好的扩展性、灵活性，可能需要对原有的功能做一些取舍。</p>
<p>下面我们将介绍一下CAP理论，它会从理论的角度告诉我们鱼和熊掌不可兼得</p>
<h1 id="CAP理论"><a href="#CAP理论" class="headerlink" title="CAP理论"></a>CAP理论</h1><p>所谓CAP(Consistency , Availability , Partition Tolerance）理论，指的是一致性、性能、扩展性无法完全兼顾。也就是，我们想要良好的扩展性，则就无法像传统关系型数据那样能保证强一致性。</p>
<p>到底要不要保证<strong>强一致性</strong>，主要看客户的<strong>业务</strong>是否需要强一致性呢？</p>
<p>比如DNS解析，更换主机之后暂时不能全网刷新，这种短暂的不一致是可以接受的。</p>
<p>不过也不是完全不能保证一致性，我们有个模型叫<strong>NWR模型</strong>，可以在一致性和性能上实现平衡。</p>
<ul>
<li><p><code>N</code>表示数据块的副本数，</p>
</li>
<li><p><code>W</code>表示写入几份就返回成功。</p>
</li>
<li><p><code>R</code>表示为了保证读一致，客户端需要从保存副本的<code>N</code>个节点中的几个同时读出数据。</p>
</li>
</ul>
<p>比如N=3，W=1，也就是保存3副本，写入1份数据就返回成功。</p>
<ul>
<li><p>如果R=1，当写入一份数据并返回成功以后开始读，因为同时只读一份数据，则既可能从未更新的两份数据中读，又可能从刚刚更新的数据中读，所以有可能读到未更新的版本。</p>
</li>
<li><p>如果R=2，同样也不能保证一定读到最新更新的版本。</p>
</li>
<li><p>如果R=3，则一定可以保证读到的3份数据有一份是最新的，只需要看谁的时间戳更晚就行。</p>
</li>
</ul>
<p>如果W=2，就必须同步写成功2个副本才返回后成功，读的时候，只需要读2份就能保证最新了。</p>
<p>总结一下，只要$W+R&gt;N$，就可以保证读一致。</p>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-25dd035523a5b9d4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<h1 id="NoSQL"><a href="#NoSQL" class="headerlink" title="NoSQL"></a>NoSQL</h1><p>弱一致性的<strong>数据库集群</strong>一般都不支持事务，同时也不支持<strong>关联查询</strong>，为什么呢？因为关联查询需要其他节点提供<strong>数据分片</strong>，也就是说一次查询需要调动其他的节点，这样并发性能将会非常差。</p>
<p>这种去掉关联性，只能保证弱一致性的轻量级的分布式数据库系统，就属于 <strong>NoSQL系统</strong></p>
<p>NoSQL被我们用得最多的当数key-value存储，当然还有其他的文档型的、列存储、图型数据库、xml数据库等。</p>
<h2 id="NoSQL分类"><a href="#NoSQL分类" class="headerlink" title="NoSQL分类"></a>NoSQL分类</h2><p>我们对现有的NoSQL进行简单的分类。</p>
<table>
<thead>
<tr>
<th>类型</th>
<th>部分代表</th>
<th>特点</th>
</tr>
</thead>
<tbody><tr>
<td>列存储</td>
<td>Hbase</td>
<td>方便做数据压缩，对针对某一列或者某几列的查询有非常大的IO优势。</td>
</tr>
<tr>
<td>文档存储</td>
<td>MongoDB</td>
<td>JSON。因为存储的内容是一个文档，所以可以对某些字段建立索引</td>
</tr>
<tr>
<td>key-value存储</td>
<td>Redis/Memcache</td>
<td>可以通过key快速查询到其value</td>
</tr>
<tr>
<td>图存储</td>
<td>Neo4J</td>
<td>如要存储的是图形关系，使用这种方式最好。</td>
</tr>
<tr>
<td>对象存储</td>
<td>db4o/Versant</td>
<td>通过对象的方式存取数据。</td>
</tr>
<tr>
<td>xml数据库</td>
<td>Berkeley DB XML</td>
<td>支持XML的内部查询语法，比如Xpath。</td>
</tr>
<tr>
<td><img src="http://upload-images.jianshu.io/upload_images/1323506-63367efe04b96b66.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></td>
<td></td>
<td></td>
</tr>
</tbody></table>
<h2 id="优势"><a href="#优势" class="headerlink" title="优势"></a>优势</h2><ul>
<li><p>更加的灵活</p>
<p>  关系型数据库需要事先设定要数据字段，而NoSQL存储方式是键值对、列存储等，更加的灵活，特别适合处理非结构化、半结构化得的数据。</p>
</li>
<li><p>易扩展：去掉了关系数据库的关系型特性，数据无关系，更易于扩展。</p>
</li>
</ul>
<ul>
<li>高性能：因为NoSQL去掉了关系性，数据库结构简单，性能自然更高。</li>
</ul>
<ul>
<li><p>高可用：大多数NoSQL数据支持<strong>自动复制</strong>，可以可以在不太影响性能的情况下，方便的实现高可用架构。</p>
</li>
<li><p>自动分片：</p>
<p>  关系型数据因为是结构化的，所以一般来说都是垂直扩展，也就意味着单台服务器需要持有整个数据库，扩展性自然不好。</p>
<p>  NoSQL一般都支持<strong>自动分片</strong>，也就是会自动向多台服务器上分发数据，这一切是对应用透明的。</p>
</li>
</ul>
<h2 id="缺点"><a href="#缺点" class="headerlink" title="缺点"></a>缺点</h2><p>了解了优点我们也需要了解NoSQL的缺点。</p>
<p>NoSQL相对于关系型数据库，放弃了很多功能，比如事务、一致性等，而且目前来说还不够成熟，同时很多NoSQL不提供SQL支持。</p>
<p>所以最好的方法是了解那些场景适合NoSQL，然后与万能的关系型数据库结合来使用<br><img src="http://upload-images.jianshu.io/upload_images/1323506-2574ad282ae53f44.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<p>一些涉及到K-V的存储、用户密码存储、Session会话存储等，可以使用NoSQL</p>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

        
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="en">
    <link itemprop="mainEntityOfPage" href="https://duyang2903.gitee.io/2019/11/15/%E5%A4%A7%E8%AF%9D%E5%AD%98%E5%82%A8%EF%BC%8C%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%887%E7%AB%A0%EF%BC%89%EF%BC%8COSI/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="dy2903">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="dy2903的博客">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          
            <a href="/2019/11/15/%E5%A4%A7%E8%AF%9D%E5%AD%98%E5%82%A8%EF%BC%8C%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%887%E7%AB%A0%EF%BC%89%EF%BC%8COSI/" class="post-title-link" itemprop="url">大话存储，学习笔记（7章），OSI</a>
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">Posted on</span>

              <time title="Created: 2019-11-15 10:48:24" itemprop="dateCreated datePublished" datetime="2019-11-15T10:48:24+08:00">2019-11-15</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">Edited on</span>
                <time title="Modified: 2019-11-13 21:27:13" itemprop="dateModified" datetime="2019-11-13T21:27:13+08:00">2019-11-13</time>
              </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>任何系统之间，如果需要通信，都需要一套自己的协议系统。这个协议系统一般要定义互相通信的语言，以及硬件。</p>
<p>OSI是被提取抽象出来的系统间通信模型，中文意思是“开放式系统互联”，是描述多个系统之间交流的通用模型。</p>
<h1 id="OSI模型"><a href="#OSI模型" class="headerlink" title="OSI模型"></a>OSI模型</h1><h2 id="OSI初步"><a href="#OSI初步" class="headerlink" title="OSI初步"></a>OSI初步</h2><p>在讲OSI之间，我们首先看一个例子，PC a向PC b发送数据包的过程如下：</p>
<ul>
<li><p>a在<strong>内存</strong>中通过定义的语言生成数据包</p>
</li>
<li><p>将数据包通过总线传给<strong>TCP/IP协议处理单元</strong>，告诉对方的IP地址、UDP还是TCP、端口号</p>
</li>
<li><p>TCP/IP处理模块收到包之后，封装，通过总线发送给<strong>以太网卡</strong></p>
</li>
<li><p><strong>以太网卡</strong>再进行编码，变成高低电平震荡发给<strong>交换机</strong></p>
</li>
<li><p>交换机将数据包交换到b的接口</p>
</li>
<li><p>b输送到<strong>以太网卡</strong>的解码芯片，去掉以太网头然后产生<strong>中断</strong>，将数据包送到内存</p>
</li>
<li><p>TCP/IP处理模块提取IP头和TCP头，以便区分应该输送到哪个应<strong>用程序的缓冲区内存。</strong></p>
</li>
<li><p>送到b的应用程序缓冲区内存</p>
</li>
</ul>
<p>可以发现里面最重要的就是三个<strong>元素</strong></p>
<ul>
<li><p>连：通信双方需要连通起来。</p>
</li>
<li><p>找：指的是通信双方必须能区分自己和对方。</p>
</li>
<li><p>发：定义了如何将数据发到对方。</p>
</li>
</ul>
<h2 id="OSI的七个层次"><a href="#OSI的七个层次" class="headerlink" title="OSI的七个层次"></a>OSI的七个层次</h2><p>OSI模型将系统通信划分为了7个层次，最上面的三个层次可以归属到应用层。这个层不需要关心如何将数据传送到对方，只关心如何组织和表达数据。</p>
<h3 id="应用层"><a href="#应用层" class="headerlink" title="应用层"></a>应用层</h3><p>应用层是OSI的最上层，表示一个系统对另一个系统要传达的最终消息。</p>
<p>只关注数据， 不关注指令如何发送</p>
<h3 id="表示层"><a href="#表示层" class="headerlink" title="表示层"></a>表示层</h3><blockquote>
<p>表示层就是对应用层数据的一种表示。</p>
</blockquote>
<p>发送方必须用双方规定好的格式来表示信息：可以嵌入在实体数据中。</p>
<h3 id="会话层"><a href="#会话层" class="headerlink" title="会话层"></a>会话层</h3><blockquote>
<p>会话层：建立会话交互机制。实际是双方的应用程序之间的交互。</p>
</blockquote>
<p>应用层、表示层、会话层的数据内容都被封装起来，交给<strong>押运员</strong><code>传输层</code>。</p>
<p>TCP/IP只有4层：应用层、传输层、网络层、物理链路层，它将OSI的应用层、表示层、会话层合并为一层，即<code>应用访问层</code>。意思是这个层全部与应用程序相关的逻辑，与网络通信无关。应用程序只需要调用下层的接口就可以完成通信。</p>
<p><strong>下四层的作用是把上三层的数据成功送到目的地。</strong></p>
<h3 id="传输层"><a href="#传输层" class="headerlink" title="传输层"></a>传输层</h3><p>典型的传输层程序如下：</p>
<ul>
<li><p>TCP协议的作用是保证上层数据能传输到目的地。类似货运公司的<strong>押运员</strong>，不管通过什么渠道（直达还是下一跳），不管物理链路的类型，只要送到即可。</p>
</li>
<li><p>如果出现错误，需要<strong>重新发送</strong>。每件货物到了目的地必须找收件人签字（<strong>TCP的ACK应答包</strong>）或者一批货物到了以后一次性签收。（<strong>滑动窗口</strong>）</p>
</li>
<li><p>最后回公司登记</p>
</li>
</ul>
<p><strong>TCP主要处理拥塞和流量控制。</strong>路由器是调度中心，它可以决定走哪条路。TCP不能调度，它只是在发生了拥挤就只能通知后续的货物慢点发。如果道路畅通，则通知后面的货物加速发送。</p>
<p>那么TCP是怎么知道链路是否拥塞呢？它可以通过接收方返回的<strong>ACK应答</strong>来判断链路拥挤的。如果半天都没收到对方的签字，说明拥塞，有丢失</p>
<p> ** 传输层的程序一定运行在通信双方的终端设备上。**而不是在中间的互联设备上。</p>
<p> 因为传输层是一种<strong>端到端</strong>的保障机制，必须保证成功收到了并<strong>成功处理数据</strong>，才算发送成功了。如果只到了对方的网卡，但是断电了，也不叫端到端保障。</p>
<p>具体的可以再看<a href="http://www.cnblogs.com/dy2903/p/8311088.html" target="_blank" rel="noopener">从输入网址到浏览器返回内容（二），TCP/IP篇</a></p>
<h3 id="网络层"><a href="#网络层" class="headerlink" title="网络层"></a>网络层</h3><p>上面说到了传输层其实只是一个<strong>押运员</strong>，它并不能进行调度，那么如何选路就交给了网络层。</p>
<p>同样以客户寄货物为例，当客户把货物交给货运公司的时候，会填写目的地址，至于应该走哪条路，统统不管，全部交给网络层处理。</p>
<ul>
<li><p>货运公司为每件货物贴上<strong>IP头地址标签</strong></p>
</li>
<li><p>货运公司掌握了全球范围的地址信息（<strong>路由表</strong>）</p>
</li>
<li><p>选择了一条路就上路。</p>
</li>
<li><p>货物每中转到一个地方就交给<strong>那个地方的调度</strong>，由调度来决定下一站到哪里。</p>
</li>
<li><p>旧调度不必告诉新调度最终的目的怎么走，因为所有调度都知道<strong>最终的目的。</strong></p>
</li>
</ul>
<p>总结一下就是，客户寄送货物的时候需要给出最终的目的地址，不管这个货物途径哪个<strong>中转站</strong>，所有的中转站都会知道最终的目的地址。</p>
<p>比如，要从新疆将货物寄到青岛，但是新疆到青岛没有直到的火车，所以只能去北京转出。</p>
<p>那么新疆的调度会去查找路由表，发现必须先到北京。注意此时在货物上贴上的还是<strong>青岛</strong>的标签，而不是北京的标签，但是会将货物发到去北京的火车上。</p>
<p>货物到北京，查看最终的目的地，会查找北京调度中心的路由表，此路由表与新疆的表不同。于是将货物送到去青岛的火车。</p>
<p>可以看出** 路由器就是调度的角色**</p>
<p>比如从青岛访问北京的服务器，具体步骤如下：</p>
<ul>
<li><p>首先必须知道服务器的IP地址，用这个IP地址作为最终目的地址组装成数据包，发送给青岛的Internet提供商（下面叫<strong>运营商</strong>）的路由器</p>
</li>
<li><p>运营商的路由器解析目的IP地址，发现应该从1号端口发送出，于是发到了<strong>河北</strong>的另一台路由器。</p>
</li>
<li><p>河北路由器根据目的IP查找路由表，发现需要从8口出</p>
</li>
<li><p>多次中转以后，发到了北京的路由器。</p>
</li>
<li><p>最终到了北京的服务器，将这个包传送到这台服务器的<strong>网卡</strong>，并提交到TCP/IP协议处理的内存空间。</p>
</li>
<li><p>发现是一个TCP握手数据包，所以返回一个确认包，三次握手完成后，就可以向服务器发送HTTP请求来获取网页资源。</p>
</li>
</ul>
<p>在中转的过程中，目的IP并不会改变，改变的只是MAC地址，也就是说会将MAC地址改为<strong>下一站</strong>的地址。</p>
<h3 id="数据链路层"><a href="#数据链路层" class="headerlink" title="数据链路层"></a>数据链路层</h3><blockquote>
<p><strong>数据链路层</strong>：连通两个设备之间的链路，将上层的数据包再次打包成对<strong>应链路特定的格式</strong>。按照对应链路的规则在链路上传输给对方。</p>
</blockquote>
<p>数据链路就好比<strong>交通规则</strong>：上路之前还需要看公路的质量怎么样，和对方商量传输的事宜。</p>
<p><strong>链路层的作用：</strong></p>
<ul>
<li><p>协商链路参数：双工、速率、链路质量</p>
</li>
<li><p>打包成<strong>帧</strong>，加上同步头，一次传输一句或者一个字符一个字符（取决于上层的选择）</p>
</li>
<li><p>链路层程序调用物理层提供的接口，将帧交给物理层。</p>
</li>
<li><p>提供一些保障机制，在每个帧之后加一个校验字段。如果不符说明链路干扰，直接丢弃，不过<strong>不会报告错误</strong>，因为上层对链路层的错误不关心。接收方的传输层会感知某个包没有到达，重新传送不完整的包。链路层只侦错，不纠错。</p>
</li>
</ul>
<p><strong>两台PC之间的通信和两个路由器之间通信是有区别的。</strong></p>
<p><strong>路由间的通信：</strong></p>
<p>简单的路由设备工作在OSI的第三层，即网络层，没有上4层的处理逻辑。</p>
<p>所以收到包之后，只检查包中的IP地址，<strong>不改变IP头之上的其他内容。</strong></p>
<p><strong>如果有NAT功能的路由器，会对IP包的源或者目的IP地址做修改</strong>。</p>
<p>下图为通信路径上各个设备所作用的层次示意图：<br><img src="http://upload-images.jianshu.io/upload_images/1323506-3e17ebfd8467ae39.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<ul>
<li><p>PC A上的浏览器要访问PC B上的Web服务，首先调用WinSock接口，访问<strong>OS内核</strong>中的TCP/IP协议栈，将<strong>目的IP和目的端口以及数据（HTTP GET请求）</strong>告诉TCP/IP协议栈</p>
</li>
<li><p>协议栈发现与<code>PC B</code>不存在链接，所以通过三次握手与B的协议栈建立连接。<br>（A的协议栈组装第一次<strong>握手包</strong>，发给OS的内核缓冲区，调用网卡驱动从缓冲区将IP包编码并传递出去，因为握手包很小，所以只需要一个帧。）</p>
</li>
<li><p>帧到达路由器A的缓冲区，产生<strong>中断</strong>信号，去掉以太网头，发送到<code>路由器A</code>的内存，等待IP转发逻辑块处理（IP路由协议计算模块），分析出IP包的头部目的IP地址，查找路由表确定出去的端口号</p>
</li>
<li><p>查找出后，从<code>网卡2</code>出发送到<code>路由器B的网卡2</code>.通过同样的过程，发送到<code>PC B</code>的网卡缓冲区，网卡产生<strong>中断</strong>，通过总线传送到TCP/IP的协议栈缓冲区内存。</p>
</li>
<li><p><code>PC B</code>的协议栈分析出IP是自己的，端口号是80，同时握手标识位是二进制1，就知道是从源设备向Web服务程序所监听的端口发起的握手连接。所以回复IP包给<code>PC A</code>，PC A再回一个最终确认的包。</p>
</li>
<li><p>握手成功，<code>PC A</code>的协议栈将缓冲区中有浏览器发送过来的HTTP GET请求数据组装成TCP/IP数据包发送给<code>PC B</code>。PC B获得数据包之后，分析TCP 端口号，根据对应关系将数据放到<strong>监听这个端口的应用程序的缓冲区内存。</strong></p>
</li>
<li><p>应用程序收到GET请求后，触发Web服务逻辑流程，返回Web数据。同样由B的协议栈发送给<code>PC机 A</code>。</p>
</li>
</ul>
<blockquote>
<p>未收到确认的包会放到缓冲区中，不会删除，直到收到对方的确认。</p>
</blockquote>
<p>所以即使中途的设备把包丢弃了，运行在两端的TCP/IP协议依然会重传，这就是端到端的保障，因为设备中途网络设备不会缓存发送的数据，更不会自动重传。</p>
<p>现在我们来对比一下IP头和TCP头的区别：</p>
<ul>
<li><p>IP头是个标签，用来查看是谁发的货物。</p>
</li>
<li><p>TCP头是用来确认由哪个上层应用程序来处理收到的包。（用端口号来决定）</p>
</li>
</ul>
<h3 id="物理层"><a href="#物理层" class="headerlink" title="物理层"></a>物理层</h3><blockquote>
<p><code>物理层</code>：在一种介质上将数据编码发送给对方。</p>
</blockquote>
<p>注意<strong>链路层是控制物理层的。</strong></p>
<p>我们可以把物理层看做<strong>传送带</strong>，不会进行货物分批，所以需要<strong>链路层</strong>给每批货物加标志性的头，接收方看到标志了以后就知道新一批货物来了。</p>
<p>经过物理层编码后，最终变成了一串bit流。通过电路振荡传输给对方，收到bit流之后，提交给链路层程序，剥去链路层同步头、帧头帧尾、控制字符。</p>
<blockquote>
<p>MTU ,最大传输单元：每种链路都有自己最合适的分批大小</p>
</blockquote>
<p>如果一次传输传送大于这个大小的货物，超过了链路接收放的处理吞吐量，会造成缓冲区溢出。</p>
<p>不过TCP和IP协议都会给货物分批。TCP会首先给货物分批，到了IP层，会按照链路层的分批大小来进行分批，如果TCP的分批大小已经小于链路层的分批，不会再分。</p>
<p>被IP层分批的货物，最终会由接受方的IP层再组装，但是由TCP分批的货物，<strong>接收方的TCP层不会合并。</strong>对货物的处理分析全部交由上层的应用程序来处理</p>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-2d0883323f2ad918.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

        
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="en">
    <link itemprop="mainEntityOfPage" href="https://duyang2903.gitee.io/2019/11/15/%E5%A4%A7%E8%AF%9D%E5%AD%98%E5%82%A8%EF%BC%8C%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%8815%E7%AB%A0%EF%BC%89%EF%BC%8C%E5%9D%97%E7%BA%A7%E9%9B%86%E7%BE%A4%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="dy2903">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="dy2903的博客">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          
            <a href="/2019/11/15/%E5%A4%A7%E8%AF%9D%E5%AD%98%E5%82%A8%EF%BC%8C%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%8815%E7%AB%A0%EF%BC%89%EF%BC%8C%E5%9D%97%E7%BA%A7%E9%9B%86%E7%BE%A4%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/" class="post-title-link" itemprop="url">大话存储，学习笔记（15章），块级集群存储系统</a>
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">Posted on</span>

              <time title="Created: 2019-11-15 10:48:24" itemprop="dateCreated datePublished" datetime="2019-11-15T10:48:24+08:00">2019-11-15</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">Edited on</span>
                <time title="Modified: 2019-11-13 21:27:13" itemprop="dateModified" datetime="2019-11-13T21:27:13+08:00">2019-11-13</time>
              </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <h2 id="存储系统演变"><a href="#存储系统演变" class="headerlink" title="存储系统演变"></a>存储系统演变</h2><p>存储系统一直以来都是一个总的控制器加上几串磁盘扩展柜存在的，但是随着数据量的快速增加，性能受限于<strong>控制器</strong>，所以要提升整体的处理能力，主要有两种方法：</p>
<ul>
<li><p>最简单的是在单个控制器中加入更多的CPU、内存等，就如同PC机性能不够了，就加内存、换SSD等。这种扩展方式称为<code>带内扩展，Scale-up</code></p>
<p>  这种方式的问题是，随着CPU数量的增多，耗费的设计成本会越来越大。比如说在多CPU的系统中，我们需要花费大量的精力来保证CPU之间的通信。可见<a href="http://www.cnblogs.com/dy2903/p/8341268.html" target="_blank" rel="noopener">【大话存储】多CPU架构变迁， SMP,NUMA,MPP</a></p>
</li>
<li><p>而多台独立的控制器形成一个集群，他们通过网络将互联起来。这种方式叫<code>带外升级，Scale-Out</code></p>
<p>  不过现在大规模主机集群没有广泛应用于企业中，原因在于集群的<code>应用程序</code>还没有跟上。我们知道传统的程序主要是运行在单机上的，并没有针对集群进行相应的优化，目前只有一些数据库等系统提供了集群方式的部署，比如Oracle RAC等。</p>
<p>  另一方面，企业又被主机性能浪费所困扰，又需要部署虚拟机系统</p>
<p>  真的是集群也不是，不集群也不是，又催生了更彻底的解决方案——<strong>云系统</strong>。</p>
</li>
</ul>
<p>好了我们重新回到集群存储系统上来，如果存储系统要做集群，数据分布方式将有两种：</p>
<ul>
<li><p>将整体数据切分成若干份，然后<strong>每一份</strong>都分开存储在单个的节点上</p>
<p>  这种方式，因为完全由系统自己决定如何切分。如果多个应用系统同时访问，有可能会影响系统整体的性能。</p>
</li>
<li><p>手动进行切分，每一份放在独立的节点上。</p>
<p>  这种方式需要更多人为干预，但是却可以保证性能资源的合理分配，每个应用系统只访问一个或者若干节点，不影响其他节点的性能。这种方式，相当于在传统架构中为每个应用建立独立的Raid Group一样。</p>
</li>
</ul>
<p>其实一个存储系统最大的<strong>问题</strong>在于<strong>在多主机并发访问时，如何能保证系统的性能</strong>，目前主要是通过<strong>隔离资源的方法</strong>来解决。</p>
<p>所以对于主机而言，只能看到自己的LUN，只是这些LUN是虚拟出来的，可以进行集中管理。</p>
<p>我们可以把集群存储系统分为如下三种：</p>
<ul>
<li><p>块存储系统</p>
</li>
<li><p>NAS集群系统</p>
</li>
<li><p>文件系统集群</p>
</li>
</ul>
<p>下面我们将先介绍块存储系统，主要介绍市面上几种典型的产品。<br><img src="http://upload-images.jianshu.io/upload_images/1323506-91348d6d006db630.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<h2 id="IBM-XIV集群存储系统"><a href="#IBM-XIV集群存储系统" class="headerlink" title="IBM XIV集群存储系统"></a>IBM XIV集群存储系统</h2><h3 id="组成部分"><a href="#组成部分" class="headerlink" title="组成部分"></a>组成部分</h3><p>XIV是一种<strong>网格集群化存储系统</strong>，每个节点都是一台PC Server，每个节点包含12块本地SATA盘，配置是两颗4核的CPU和8GB的内存。</p>
<p>XIV有共有两种类型的节点：Interface Node , Data Node</p>
<ul>
<li><p>只有Interface Node上插着FC HBA卡，也就说主机只能连接到Interface Module上。Interface Module本身含有12块SATA硬盘。</p>
</li>
<li><p>Data Node只有12块SATA硬盘以及两块双口千兆以太网卡。</p>
</li>
</ul>
<p>所以这两种节点都可以提供存储空间，只是说Interface Node还可以接前端的主机而已。</p>
<p>下图为集群连接拓扑。</p>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-be8e125f4875c79a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<p>下图为机柜示意图</p>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-8d86fe2b9e2d4dc1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<h3 id="LUN的分布式设计"><a href="#LUN的分布式设计" class="headerlink" title="LUN的分布式设计"></a>LUN的分布式设计</h3><p>集群系统中，LUN被平均分布在多个节点上，也就是说一块逻辑硬盘实际上会拆分成若干份，散落在不同的节点上面。那么我们怎么知道LUN分散到哪里去了呢？这就需要一个<code>映射图</code>来记录每个LUN的分布情况。</p>
<p>为了保证数据块不丢失，每个LUN对应的数据块会<code>镜像</code>一份，而且放到另一个节点上。这样纵然这个节点挂了，还可以根据<code>映射图</code>找到其镜像，然后重新复制一份到剩余空间里面。这种思想就叫<strong>多副本机制</strong>，我们把源分块称为Primary，镜像分块称为Secondary。</p>
<p>这种思想与NetApp的WAFL文件系统极为类似，实际上高度虚拟化的设备，一般来说，底层的LUN不是存在于固定的位置。比如XIV可以通过<code>映射图</code>来记录LUN在所有节点的存储地址，这就是文件系统的思想，我们知道文件系统是可以通过INode Tree来遍历整个文件的分布情况的。</p>
<p>WAFL和XIV正是对文件系统的基本思想的灵活运用，但是XIV的粒度和元数据复杂度没有WAFL那么细，所以没有沦为一个彻底的文件系统。</p>
<blockquote>
<p>所以像XIV这样的块存储系统，对内使用文件系统的基本思想进行LUN的管理，但是对外屏蔽细节，对主机而言是透明的。</p>
</blockquote>
<h3 id="如何应对客户端的写IO"><a href="#如何应对客户端的写IO" class="headerlink" title="如何应对客户端的写IO"></a>如何应对客户端的写IO</h3><p>当某个Interface Node接收到一个写IO的以后，首先会通过<strong>映射表</strong>去判断这个写IO会落到哪个节点上以及其镜像又落在哪里。有两种可能，一种是留在Interface Node 上，也可能在Data Node 上。</p>
<ul>
<li><p>如果是落在Interface Node本地硬盘中，则会将<strong>副本</strong>发送到分块镜像所在的Node中。<br>然后返回成功。</p>
</li>
<li><p>如果是放到另外的节点中，则Interface Node重定向这个写IO到该节点中。应该保存Primary分块的节点会再次根据<strong>映射表</strong>把分片数据复制到副本节点中。<br>当副本也写入成功了以后，才会向最初的Interface Node返回成功回应。由Inteface Node向客户端返回成功。</p>
</li>
</ul>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-1bc1baa3ac7d4caf.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<p>总结一下，就是Interface Node会接收到主机的写IO请求，如果发现是写到自己的内部硬盘上，则复制两份到副本节点上。</p>
<p>如果Inteface Node发现数据是写到其他节点上，则会将写IO重定向到对应的节点上，由该节点复制两份数据到其他节点。当所有的写入都成功了以后，才会向最初的Interface Node返回成功，注意，此时仍由Inteface Node 向主机返回成功，也就意味着，主机其实不知道数据被重定向走了，它仍然以为自己在和此Inteface Node 交互数据呢。</p>
<h3 id="XIV快照设计"><a href="#XIV快照设计" class="headerlink" title="XIV快照设计"></a>XIV快照设计</h3><p>我们知道XIV设计也使用了文件系统的思想，所以对于快照，XIV的做法与WAFL差不多，都使用Write Redirect。现在简单的讲一下。</p>
<p>XIV的卷管理模块其实是一个集群文件系统，<strong>每个LUN都对应一个分布式映射表(Distribute Map)</strong>。</p>
<p>如要要生成快照，可以将这个点数据以及映射表先冻结，然后把<strong>映射表</strong>复制一份，做为新的<strong>活动映射表</strong>，之后的针对这个LUN的写IO都会被<strong>重定向</strong>到空闲数据块上，并把<strong>映射表</strong>更新。</p>
<p>所以再生成快照就简单了，只需要把活动的映射表复制一份即可，这就是<strong>Write Redirect</strong>模式。</p>
<h3 id="故障恢复"><a href="#故障恢复" class="headerlink" title="故障恢复"></a>故障恢复</h3><p>XIV对数据分布的本质思想是<code>分布式RAID 10</code>，相当于将一个LUN复制一份，副本保存在其他位置，这样系统的可用容量相当于减半了，我们可以把这种设计称为<code>上层分布式RAID 10</code>。</p>
<p>那么这种RAID 10的做法与传统的RAID 10有什么区别呢？</p>
<p>我们传统的RAID 10不管底层有没有数据占用，都会将所有数据块<strong>镜像</strong>起来，浪费了很多空间。这是因为判断有用或者是没有是上层的文件系统来做的，传统的RAID 10根本无法判断，所以只能一股脑的镜像。</p>
<p>XIV相当于一种粗粒度的文件系统，它可以在上层对数据块是否有用进行判断。</p>
<p>下面来具体看看XIV是怎么做：</p>
<ul>
<li><p>不需要备份无用的块：XIV卷管理系统相当于一个粗粒度的文件系统，LUN就是它管理的文件，所以它可以感知LUN分块占用了磁盘的哪块空间。也就是说卷管理系统完全可以只镜像部分LUN分块，而无须做其他的无用功。</p>
</li>
<li><p>分布式</p>
<p>  假设LUN被分为6块数据块，分别标记为B1<del>B6，镜像块为M1</del>M6。</p>
</li>
</ul>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-6facf61bf4e2ce23.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<p>如果D1故障，为了恢复数据的冗余，可以将镜像块M1~M3复制到D3和D4磁盘中。</p>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-7df2dd93a39d7ccf.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="D1故障"></p>
<p>如果<code>D3</code>又故障了，那么数据还是没有丢失，依然继续复制。此时还有冗余性，存在一份副本。</p>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-a4939110092e1bdc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="D3故障"></p>
<p>此时如果D2或者D4发生了故障，则没有冗余性了，但是数据仍然没有丢失。</p>
<p>此时如果手动添加了两块硬盘，XIV会重新平衡数据。如下图：</p>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-98504275e049ee7f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<p>XIV的这种上层RAID 10设计可以随时迁移数据块，并且可以任意分布式摆放数据块，不受磁盘数量限制。只受系统内剩余空间限制。我们把这种模式叫<code>上层分布式RAID 10</code></p>
<p>那么与传统的RAID 10有什么区别。传统的RAID 10在一块盘故障之后，只能将数据镜像到新盘里面。</p>
<p>目前发布的XIV系统，最大配置为6个Interface Node和9个Data Node，最大磁盘数为15<em>12 = 180块。XIV这种架构设计可以很容易的*</em>扩充节点**</p>
<h3 id="XIV优点"><a href="#XIV优点" class="headerlink" title="XIV优点"></a>XIV优点</h3><p>下面我们来看一下XIV相对于传统架构有什么优点：</p>
<ul>
<li><p>如果此时系统还有剩余的磁盘空间，只要磁盘一块一块的坏下去，整体数据的冗余性可以保持，直到一点空间都没有的时候。当然前提是，当一个磁盘或者节点坏了以后，需要Rebuild，也就是只有在Rebuild以后，才允许再坏一块硬盘，否则有可能数据被损坏。</p>
</li>
<li><p>另一个优点在于恢复的速度上，它的Rebuild时间短，一个1TB容量的SATA盘损坏之后，Rebuild时间只有30分钟作用，为什么这么快呢？</p>
<ul>
<li><p>原因一：XIV使用的是RAID 10的思想，而不是RAID 5。</p>
<p>这样XIV没有校验盘，不需要计算校验值，也不需要把校验值放到其他空间里面，节省了大量计算资源和IO资源。所以XIV的恢复时间比RAID 5快十几倍很正常。</p>
<p>我们可以简单的对比一下。假设有180块硬盘，组成大RAID 5，此时坏了一块盘，系统需要从剩下的盘里面读所有的数据。</p>
<p>若一块盘容量为1TB，<strong>内部磁盘环路带宽</strong>为4Gb，需要耗费时间（179TB/4Gb）/3600=130.3小时，与XIV的30分钟相比，反差巨大。</p>
<p>还可以与传统的RAID 10对比一下。180块盘组成RAID 10，其中90块数据盘和90块镜像盘，如果一块盘故障，会从对应的镜像盘中读数据。由于是RAID 10，不需要计算XOR等，可以<strong>整盘复制</strong>，所以是<strong>连续读写</strong>，可以达到磁盘的最大吞吐。SATA硬盘的理论连续读吞吐量为60MB/s，所以Rebuild时间为（1TB/60MB/s）/3600 = 4.85小时，为XIV的10倍。因为RAID 10需要整盘复制。</p>
</li>
<li><p>原因二：分布式。</p>
<p>传统RAID 10中，一块盘坏了，只能从镜像盘中取数据，写到新盘上，也就是一个盘读，一个盘写。</p>
<p>而XIV是将LUN分块平衡存放到多个磁盘上，而这些分块对应的镜像也是存放在多块磁盘。所以XIV在 Rebuild的时候，是从多块盘读，多块盘写，相当于RAID 3，众人拾柴火焰高，恢复速度当然快。</p>
</li>
<li><p>原因三：最重要的原因，不做<strong>无用功。</strong></p>
<p>Rebuild的时候，只使用了已占用的数据块，而<strong>不是整块盘</strong>。</p>
</li>
</ul>
</li>
</ul>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-c99cbdac4a542f9c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<h2 id="3PAR公司Inserv-T800集群存储系统"><a href="#3PAR公司Inserv-T800集群存储系统" class="headerlink" title="3PAR公司Inserv-T800集群存储系统"></a>3PAR公司Inserv-T800集群存储系统</h2><p>Inserv-T800为一款x86集群式存储系统。</p>
<p>每个节点都是一台x86 Server，整个集群可以由2~8个节点组成。系统所有节点两两直通，每两个节点使用一条独立的100MHz 64b PCI-X总线相连。</p>
<p>比如一个8节点的系统，1个节点需要与另外7个节点互联，所以每个节点都需要7条PCI-X总线连接到背板，形成一个具有28条直通PCI-X的星形结构。</p>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-bf93d5bc42e43cab.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<p>PCI-X是半双工的，所以内部互联带宽为28*800MB/s=21.875GB/s。</p>
<p>不过因为PCI-X并非一种包交换网络传输模式，<strong>所以背板不需要加电，</strong>是一块布满导线和接口的被动式背板。也正因为此，只用了两个控制器，则只用到一条PCI-X作为互联.</p>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-01126d40a02e3be4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"><br>上图为单节点内部的架构，其中ASIC芯片是比较独特的。它将Thin Provision和LUN Shrink功能内嵌到芯片里面来执行。</p>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-2a0022c1f25eff99.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<p>3PAR扩展柜很有特色：在4U的空间放置40块3.5的大盘。因为磁盘可以竖着插而且紧密排列，所以散热和共振的问题也解决了。</p>
<p>特点：</p>
<ul>
<li><p>使用直连的PCI-X总线作为节点之间的互联。但是因为使用点对点的互联，而不是使用交换的方式，<strong>系统的扩展性很有限</strong></p>
</li>
<li><p>节点内部使用ASIC来实现大部分的数据操作，而且还负载Thin Provision和LUNShrink(Space Reclaiming)，降低了CPU的负担。而且扩展柜的高密度设计，减少了空间和连线，降低了耗电。</p>
</li>
</ul>
<p>瓶颈在于每个节点使用3条1GB/s的PCI-X总线来支持6个扩展卡共4Gb/s的FC接口，有些不够。所以系统吞吐量上不去。</p>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-b5ec481f2a5d269f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

        
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="en">
    <link itemprop="mainEntityOfPage" href="https://duyang2903.gitee.io/2019/11/15/%E5%A4%A7%E8%AF%9D%E5%AD%98%E5%82%A8%EF%BC%8C%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%8813%E7%AB%A0%EF%BC%89%EF%BC%8C%E5%8D%8F%E8%AE%AE%E8%9E%8D%E5%90%88/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="dy2903">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="dy2903的博客">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          
            <a href="/2019/11/15/%E5%A4%A7%E8%AF%9D%E5%AD%98%E5%82%A8%EF%BC%8C%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%8813%E7%AB%A0%EF%BC%89%EF%BC%8C%E5%8D%8F%E8%AE%AE%E8%9E%8D%E5%90%88/" class="post-title-link" itemprop="url">大话存储，学习笔记（13章），协议融合</a>
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">Posted on</span>

              <time title="Created: 2019-11-15 10:48:24" itemprop="dateCreated datePublished" datetime="2019-11-15T10:48:24+08:00">2019-11-15</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">Edited on</span>
                <time title="Modified: 2019-11-13 21:27:13" itemprop="dateModified" datetime="2019-11-13T21:27:13+08:00">2019-11-13</time>
              </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <h1 id="协议融合"><a href="#协议融合" class="headerlink" title="协议融合"></a>协议融合</h1><p>TCP/IP满足了Internet范围的网络通信，FC满足了后端存储的专用高速公路，而SCSI不适合Internet的通信。这就如同火车或者汽车，同样是运输货物，但是它们都适应了不同的需要。</p>
<p>对于SCSI而言，如果要跨越大范围的通信，就要将其承载到TCP/IP上，形成了ISCSI协议。TCP不用关心SCSI协议的什么，只需要封装和传输。</p>
<p>同样的道理，以太网是面向无连接的，没有握手过程，也没有终端认证机制，没有NCP（PPP用来协商上层参数的），而PPP却有，所以PPP适合ISP对接入终端进行<strong>认证</strong>。但是PPP不如以太网广泛，所以可以融合成为<code>PPPoE</code></p>
<h2 id="网络通信协议的四级结构"><a href="#网络通信协议的四级结构" class="headerlink" title="网络通信协议的四级结构"></a>网络通信协议的四级结构</h2><p>网络通信协议一般可以分为：Payload 层、信息表示层、交互逻辑层、寻址层<br>其中最重要的是<strong>交互逻辑层</strong></p>
<h3 id="Payload层"><a href="#Payload层" class="headerlink" title="Payload层"></a>Payload层</h3><p> <code>payload</code>指的是与本协议逻辑无关的最终数据，它可以是最终应用的数据，也可以是另一种协议的<strong>信息表示层+Payload</strong></p>
<p><strong>协议A</strong>封装了<strong>协议B</strong>的 “信息表示层+Payload数据”，可以说协议A封装了协议B，或者A承载了B，或者说B is over A( BoA )</p>
<p>而<code>AmB</code>则是一种彻底的协议转换，而不是仅仅做隧道封装，描述一种协议被<strong>Map</strong>到另一种协议。</p>
<h3 id="信息表示层"><a href="#信息表示层" class="headerlink" title="信息表示层"></a>信息表示层</h3><blockquote>
<p><strong>信息表示层</strong>是附加到Payload数据之外的一段数据，是协议开销。就如同在信封上的姓名一样</p>
</blockquote>
<p>比如运行在通信双方的通信协议用来交互各自的状态，比如信封上的姓名等。</p>
<h3 id="交互逻辑层"><a href="#交互逻辑层" class="headerlink" title="交互逻辑层"></a>交互逻辑层</h3><blockquote>
<p><strong>交互逻辑层</strong>其实就是运行在通信双方协议系统上的<strong>动作程序代码逻辑</strong>，它根据对方传送来的信息表示层数据作出动作。返回自己的信息表示层。</p>
</blockquote>
<p><strong>交互逻辑层</strong>是协议的设计思想，是协议的灵魂。</p>
<h3 id="寻址层"><a href="#寻址层" class="headerlink" title="寻址层"></a>寻址层</h3><p>寻址层顾名思义是找到目标的一套编址和寻址机制。不同协议的寻址层可以互相映射翻译。</p>
<blockquote>
<p>总结一下，</p>
<ul>
<li>Payload和信息表示层就是报文要承载的部分，</li>
</ul>
</blockquote>
<blockquote>
<ul>
<li>交互逻辑是协议的规范，规定了协议如何进行交互。</li>
</ul>
</blockquote>
<blockquote>
<ul>
<li>寻址层是协议的编址方式，用于区分不同的节点。</li>
</ul>
</blockquote>
<h2 id="协议融合的三种方式"><a href="#协议融合的三种方式" class="headerlink" title="协议融合的三种方式"></a>协议融合的三种方式</h2><p>协议与协议相互作用有三种方式：</p>
<ul>
<li><p>调用：一种协议完全利用另一种协议</p>
</li>
<li><p>隧道封装（Tunnel）：一种协议将另一种协议完整打包</p>
</li>
<li><p>映射（Map）：一种协议对另一种协议进行翻译，只将原来协议的Payload层数据提取，重新打包到新的协议数据包中。这种方式最彻底</p>
</li>
</ul>
<p>下面将就这几种方式进行一一讲解。</p>
<h3 id="调用"><a href="#调用" class="headerlink" title="调用"></a>调用</h3><p><strong>因为协议自身没有某些功能，</strong>所以需要调用其他协议的某些功能。</p>
<p>比如</p>
<ul>
<li><p>TCP需要调用IP，因为TCP没有寻址的功能。IP调用以太网，因为IP没有链路传输的功能。</p>
</li>
<li><p>IP调用PPP：就是上层协议为了达到通信目的，使用另一种协议来服务。</p>
</li>
</ul>
<h3 id="隧道"><a href="#隧道" class="headerlink" title="隧道"></a>隧道</h3><blockquote>
<p>将一种协议的完整数据包（包括Payload和协议开销）作为另一种协议的Payload进行封装。</p>
</blockquote>
<p>也就是说协议转换的设备只是将数据包通通打包即可，不需要关心内层协议是什么。此时需要与上面的<strong>调用</strong>进行区别，如果一种协议在某方面的功能，另一协议没有实现，就是调用。比如IPoE，IP没有链路层功能，所以是IP协议调用底层的以太网协议。不过值得注意的是IP与以太网之间的<strong>编址逻辑</strong>是映射而不是使用关系，因为我们是把IP地址<strong>映射</strong>到MAC地址上的。</p>
<p>Tunnel主要用于内层协议和外层协议都在某方面有相似的功能，但是在某些条件下，外层协议更优秀的情况下。比如用船来装火车箱，这样就可以在水路上走了。或者说还可以用于<strong>伪装内层存协议。</strong></p>
<p>ISCSI 和PPPoE是典型的Tunnel。何以见得，在ISCSI中，TCP/IP可以实现寻址和传输保障，而SCSI协议也可实现寻址和传输保障。他们都可以实现同样的功能，但是在两种协议融合以后，SCSI协议的寻址传输保障功能就不用了，完全只使用TCP/IP的。</p>
<p>上面还说过<strong>Tunnel另一个作用是伪装</strong>，也就是两种协议实现的功能、适用 的环境都相同，但是我们还是可以通过隧道进行伪装，这样对外就可以屏蔽内部细节。比如IP协议中的GRE（通用路由封装）</p>
<p>那么这种伪装有什么作用呢？它将IP协议承载到IP协议本身上面，因为多封装了一层，可以使得一些不能在公网路由的IP包，封装到可以在<strong>公网</strong>进行路由的IP包里面。</p>
<p>这又有什么用呢？比如总部和分支不在一个地方，所以中间可能会跨越<strong>Internet</strong>网络，但是我们又希望总部和分支在一个内网下。此时有两种方案：</p>
<ul>
<li>使用专线，也就是向运营商租用专用网络，好处是稳定，缺点是太贵。</li>
<li>直接使用Internet网络。但是我们知道，Internet网络的IP地址和企业内部的IP地址完全不同。那么此时Tunnel就有用了，可以在内网报文外面再封装一层，这样两端就像在一个内网里面一样，经过Internet的时候，使用公网地址封装内网的IP包，还可以对IP包进行加密、反修改等，这就形成了IPSec</li>
</ul>
<p>下面举一个例子来说明Tunnel的过程，同样以寄信为例</p>
<ul>
<li><p>寄信人将信件（Payload）装入信封（表示层数据）</p>
</li>
<li><p>填好收信人的地址、邮编等（通信协议的信息表示层、寻址层）</p>
</li>
<li><p>交给邮局（网络交换路由设备）</p>
</li>
<li><p>物流业借助水陆空等“链路层”。建立了自己的流程体系（协议交互逻辑）</p>
</li>
<li><p>用户可把信件封装到邮政普通的信封直接发，也可以封装到快递公司的信封发送，</p>
</li>
<li><p>把邮政协议Tunnel到快递公司的可以获得快速、优质的服务。</p>
</li>
</ul>
<p>若A快递公司在北京没有送货机构，但是青岛需要向北京送货？</p>
<p>可以让有送货机构的B快递公司代送，到目的地以后B的送货员剥开了信封，用户收到了快递A的信封，以为是A送过来的，这就是<strong>伪装。</strong></p>
<h3 id="映射关系"><a href="#映射关系" class="headerlink" title="映射关系"></a>映射关系</h3><p>Map比Tunnel更复杂，更融合。</p>
<blockquote>
<p>Map就是将一种协议逻辑翻译成另一种协议逻辑，Payload数据完全不变。</p>
</blockquote>
<p>内层的Payload层在Map里面不会改动，因为只有两端的通信应用程序才能理解。</p>
<p>比如A将青岛地区的送货外包给B，但是表面上必须保持A的原样。</p>
<p>起初：客户信件放入A信封，再封装成B，这就是Tunnel。</p>
<p>现在：</p>
<ul>
<li><p>让B的取件人了解寄件人提供的信息，取代了A公司的角色，用户按照A公司的协议将信封头信息告诉取件人。</p>
</li>
<li><p>取件人直接将信件装入了B的信封，但是将A的信封头转换为了B的信封头。</p>
</li>
<li><p>B转发以后，送货员将B的信封头转换为A的信封头。</p>
</li>
</ul>
<p>不过两端的用户感受不到，因为中间是有B完成的。</p>
<p>Map方式最大的好处在于<strong>开销变小。</strong></p>
<p>比如IP地址必须要映射到MAC地址才能享受以太网服务<br><img src="http://upload-images.jianshu.io/upload_images/1323506-c49b45c88845fe2a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

        
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="en">
    <link itemprop="mainEntityOfPage" href="https://duyang2903.gitee.io/2019/11/15/%E5%A4%A7%E8%AF%9D%E5%AD%98%E5%82%A8%EF%BC%8C%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%8815%E7%AB%A0%EF%BC%89%EF%BC%8C%E9%9B%86%E7%BE%A4%E6%A6%82%E8%AE%BA-1/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="dy2903">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="dy2903的博客">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          
            <a href="/2019/11/15/%E5%A4%A7%E8%AF%9D%E5%AD%98%E5%82%A8%EF%BC%8C%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%8815%E7%AB%A0%EF%BC%89%EF%BC%8C%E9%9B%86%E7%BE%A4%E6%A6%82%E8%AE%BA-1/" class="post-title-link" itemprop="url">大话存储，学习笔记（15章），集群概论-1</a>
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">Posted on</span>

              <time title="Created: 2019-11-15 10:48:24" itemprop="dateCreated datePublished" datetime="2019-11-15T10:48:24+08:00">2019-11-15</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">Edited on</span>
                <time title="Modified: 2019-11-13 21:27:14" itemprop="dateModified" datetime="2019-11-13T21:27:14+08:00">2019-11-13</time>
              </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>随着应用程序对服务器、存储系统的系统要求越来越高，单台设备有时已经无法满足需求了，此时我们有两种方法可以解决：</p>
<ul>
<li><p>使用性能更高的机器，但是成本以及维护成本非常高，而且不见得适合所有的应用。</p>
</li>
<li><p>多台设备联合起来对外提供服务，这就是集群。</p>
</li>
</ul>
<p>主机可以形成集群，存储设备也可以形成集群。目前中高端存储设备自身就有双控制器。</p>
<p>一些NAS设备可以在多台独立设备之间形成集群，并实现单一命名空间，<strong>即用户访问目录路径就像访问一台机器一样。</strong>屏蔽了后端访问的过程，实际上，可能是由集群中不同的节点来提供服务的。</p>
<h1 id="集群概述"><a href="#集群概述" class="headerlink" title="集群概述"></a>集群概述</h1><p>上面讲到了为什么要用<strong>集群</strong>，首先用多个节点来代替一个节点完成任务，处理能力可以得到提高，其实还可以获得<strong>高可用性</strong>，即一个节点发生故障，另外的节点可以接替故障节点。</p>
<p>我们可以把集群分为三种：</p>
<ul>
<li><p>高可用集群</p>
<p>  在HA集群中，节点分为<strong>活动节点和备份节点</strong>，当活动节点故障了以后，备份节点立即接替任务。</p>
<p>  那怎么实现<strong>切换的</strong>呢？HA集群的实现是基于<strong>资源切换</strong>。资源指的是备份节点要接管的所有东西，比如IP地址、磁盘卷、上下文等。</p>
<p>  那怎么知道需要主节点挂了呢？需要依靠<strong>操作系统上安装的HA软件。</strong>它可以监控对方<strong>节点状态</strong>，一旦发现故障，则强行将资源占有。</p>
</li>
<li><p>负载均衡集群</p>
<p>  负载均衡节点中，所有节点都参与工作。每个节点的地位相同，但是工作量怎么分配呢？可以有两种方式：</p>
<ul>
<li><p>由单独的节点来分配运算量</p>
</li>
<li><p>也可以由节点通过网络通信来协商。</p>
</li>
</ul>
</li>
<li><p>高性能集群</p>
<p>  又称科学计算集群，其实与负载均衡集群本质上是一样的 ，不过主要用于科学计算而已，所以这种集群主要面向与CPU消耗型的应用。</p>
<p>  如何把任务平均分配到每个CPU核心上呢？如果在一台计算机上则非常简单，操作系统会自动将<strong>多个线程平摊到多个CPU核心上</strong>。</p>
<p>  但是在集群里面，则可以通过网络来进行协商。为了方便编程，还开发出很多API，可以屏蔽很多编程复杂度。所以节点收到任务数据之后，再由节点操作系统自行将任务数据分派到多个CPU核心上。</p>
</li>
</ul>
<p><img src="http://upload-images.jianshu.io/upload_images/1323506-65a5b040487fbb06.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<h2 id="系统路径上的集群各论"><a href="#系统路径上的集群各论" class="headerlink" title="系统路径上的集群各论"></a>系统路径上的集群各论</h2><p>集群可以在系统路上的任何点实现。比如CPU、内存、显卡等硬件可以形成集群，软件上，应用程序、文件系统、卷管理系统也可以形成集群。</p>
<p>什么时候需要集群呢？</p>
<ul>
<li><p>当需要系统高可用的时候，也就是某处故障不会影响系统的可用，可选择使用高可用性集群</p>
</li>
<li><p>当单个系统的处理能力不能满足性能要求的时候，可使用负载均衡集群</p>
</li>
<li><p>当需要运算的数据量很大的时候，运算周期很长的时候，可使用高性能集群。</p>
</li>
</ul>
<p>下面我们一一谈一下硬件层面和软件层面的集群。</p>
<h3 id="硬件层面的集群"><a href="#硬件层面的集群" class="headerlink" title="硬件层面的集群"></a>硬件层面的集群</h3><p><img src="http://upload-images.jianshu.io/upload_images/1323506-14aeefaaa2da8d53.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
<ul>
<li><p>CPU集群：体现在多CPU的计算机系统，比如对称多处理系统，多个CPU共享物理内存相互协作。</p>
</li>
<li><p>内存集群：多条内存组成更大的容量空间。比如通过<strong>双通道</strong>提高性能（相当于条带化RAID0）</p>
</li>
<li><p>以太网卡集群：将多块以太网卡绑定在一起，向上提供<strong>虚拟网卡</strong>，底层则可以通过ARP轮询负载均衡，或者HA方式的多路径访问。</p>
</li>
<li><p>以太网集群：多台设备协作转发，实现了负载均衡和HA，体现在路由器和以太网交换机上。</p>
</li>
<li><p>显卡集群：将插在总线上的多块显卡连接起来，实现对大型3D数据渲染负载均衡，性能可以得到很大的提升。</p>
</li>
<li><p>FC卡的集群：通过与主机上的<strong>多路径软件</strong>配合，多块FC卡之间可以实现流量的负载均衡和HA，或者通过FC网络中的ISL链路负载均衡、HA方式实现流量分摊</p>
</li>
<li><p>FC网络设备的集群：一般来说FC网络设备没有向以太网交换机那样实现了负载均衡和HA 。</p>
</li>
<li><p>控制器集群：几乎中高端磁盘阵列的控制器都是双控的，可以是HA关系，或者是负载均衡关系。</p>
</li>
<li><p>磁盘集群:典型的集群是RAID系统，</p>
</li>
</ul>
<h3 id="软件层面的集群"><a href="#软件层面的集群" class="headerlink" title="软件层面的集群"></a>软件层面的集群</h3><ul>
<li><p>应用程序的集群：一个应用程序可以同时启动多个实例（进程），共同完成工作 。不同实例可以运行在同一机器上，也可运行在不同的机器上，通过网络交互信息。</p>
</li>
<li><p>文件系统的集群：文件系统的集群是一个比较独立的课题。可以实现集群功能的文件系统叫<strong>集群文件系统</strong>，比如NFS、CIFS等网络文件系统，就是最简单的集群文件系统。</p>
<p>  集群文件系统主要为了解决：容量、性能、共享</p>
<ul>
<li><p>解决容量问题：比如说<strong>分布式文件系统</strong>，文件的存储其实是分散在各个节点上的，但是对外呈现统一的<strong>命名空间，也即目录</strong>。</p>
<p>也就是说分布式文件系统将每个节点的可用空间进行虚拟的整合，形成虚拟目录，对外屏蔽细节，对外根据多种策略来判断数据流向，将数据写入实际的空间里面。</p>
</li>
<li><p>解决性能问题。</p>
<p>同样的，可以使用多个节点来获得高性能。集群文件系统使得每个节点不必连接昂贵的磁盘阵列，就可以获得较高的文件IO性能。</p>
<p>在分布式文件系统的<strong>虚拟整合目录</strong>之上，采用了类似条带RAID 0的方式，依据负载均衡策略，将每次IO写入的数据，负载分担到所有节点上，节点获得的性能越多提升就越大。</p>
<p>但是实际上，集群文件系统实施起来不那么容易，需要经过长时间的调优。</p>
</li>
<li><p>解决共享访问的问题。</p>
<p>这是集群文件系统要解决的<strong>最重要的问题</strong>，也就是多节点共同访问相同目录和相同文件时一致性的问题。</p>
<p>集群文件系统需要考虑多个节点同时读写相同文件，保证所有节点都能读到一致性的数据，并利用分布式锁机制保证允许的性能下，节点之间不会写冲突。</p>
<p>常用的集群文件系统有PVFS,GFS,DFS，Lustre等</p>
</li>
</ul>
</li>
<li><p>卷管理系统集群</p>
<p>  本机的卷和本机和远程的卷进行镜像等协同操作，形成集群。<br><img src="http://upload-images.jianshu.io/upload_images/1323506-7e1a02a6d51307cf.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png"></p>
</li>
</ul>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

  </div>

  
  <nav class="pagination">
    <span class="page-number current">1</span><a class="page-number" href="/page/2/">2</a><a class="extend next" rel="next" href="/page/2/"><i class="fa fa-angle-right" aria-label="Next page"></i></a>
  </nav>



          </div>
          

        </div>
          
  
  <div class="toggle sidebar-toggle">
    <span class="toggle-line toggle-line-first"></span>
    <span class="toggle-line toggle-line-middle"></span>
    <span class="toggle-line toggle-line-last"></span>
  </div>

  <aside class="sidebar">
    <div class="sidebar-inner">

      <ul class="sidebar-nav motion-element">
        <li class="sidebar-nav-toc">
          Table of Contents
        </li>
        <li class="sidebar-nav-overview">
          Overview
        </li>
      </ul>

      <!--noindex-->
      <div class="post-toc-wrap sidebar-panel">
      </div>
      <!--/noindex-->

      <div class="site-overview-wrap sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
  <p class="site-author-name" itemprop="name">dy2903</p>
  <div class="site-description" itemprop="description"></div>
</div>
<div class="site-state-wrap motion-element">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
          <a href="/archives/">
        
          <span class="site-state-item-count">20</span>
          <span class="site-state-item-name">posts</span>
        </a>
      </div>
      <div class="site-state-item site-state-tags">
        <span class="site-state-item-count">2</span>
        <span class="site-state-item-name">tags</span>
      </div>
  </nav>
</div>
  <div class="feed-link motion-element">
    <a href="/atom.xml" rel="alternate">
      <i class="fa fa-rss"></i>RSS
    </a>
  </div>



      </div>

    </div>
  </aside>
  <div id="sidebar-dimmer"></div>


      </div>
    </main>

    <footer class="footer">
      <div class="footer-inner">
        

<div class="copyright">
  
  &copy; 
  <span itemprop="copyrightYear">2019</span>
  <span class="with-love">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">dy2903</span>
</div>
  <div class="powered-by">Powered by <a href="https://hexo.io/" class="theme-link" rel="noopener" target="_blank">Hexo</a> v4.0.0
  </div>
  <span class="post-meta-divider">|</span>
  <div class="theme-info">Theme – <a href="https://pisces.theme-next.org/" class="theme-link" rel="noopener" target="_blank">NexT.Pisces</a> v7.5.0
  </div>

        












        
      </div>
    </footer>
  </div>

  
  <script src="/lib/anime.min.js"></script>
  <script src="/lib/velocity/velocity.min.js"></script>
  <script src="/lib/velocity/velocity.ui.min.js"></script>
<script src="/js/utils.js"></script><script src="/js/motion.js"></script>
<script src="/js/schemes/pisces.js"></script>
<script src="/js/next-boot.js"></script>



  
















  

  

</body>
</html>
